xref: /llvm-project/clang/docs/StandardCPlusPlusModules.rst (revision 411196b9bb1953372726348deb1bc77abfa7d900)
1b1d5af81SChuanqi Xu====================
2b1d5af81SChuanqi XuStandard C++ Modules
3b1d5af81SChuanqi Xu====================
4b1d5af81SChuanqi Xu
5b1d5af81SChuanqi Xu.. contents::
6b1d5af81SChuanqi Xu   :local:
7b1d5af81SChuanqi Xu
8b1d5af81SChuanqi XuIntroduction
9b1d5af81SChuanqi Xu============
10b1d5af81SChuanqi Xu
119263318fSAaron BallmanThe term ``module`` is ambiguous, as it is used to mean multiple things in
129263318fSAaron BallmanClang. For Clang users, a module may refer to an ``Objective-C Module``,
139263318fSAaron Ballman`Clang Module <Modules.html>`_ (also called a ``Clang Header Module``) or a
149263318fSAaron Ballman``C++20 Module`` (or a ``Standard C++ Module``). The implementation of all
159263318fSAaron Ballmanthese kinds of modules in Clang shares a lot of code, but from the perspective
169263318fSAaron Ballmanof users their semantics and command line interfaces are very different. This
179263318fSAaron Ballmandocument is an introduction to the use of C++20 modules in Clang. In the
189263318fSAaron Ballmanremainder of this document, the term ``module`` will refer to Standard C++20
199263318fSAaron Ballmanmodules and the term ``Clang module`` will refer to the Clang Modules
209263318fSAaron Ballmanextension.
21b1d5af81SChuanqi Xu
229263318fSAaron BallmanIn terms of the C++ Standard, modules consist of two components: "Named
239263318fSAaron BallmanModules" or "Header Units". This document covers both.
24b1d5af81SChuanqi Xu
25b1d5af81SChuanqi XuStandard C++ Named modules
26b1d5af81SChuanqi Xu==========================
27b1d5af81SChuanqi Xu
289263318fSAaron BallmanIn order to better understand the compiler's behavior, it is helpful to
299263318fSAaron Ballmanunderstand some terms and definitions for readers who are not familiar with the
309263318fSAaron BallmanC++ feature. This document is not a tutorial on C++; it only introduces
319263318fSAaron Ballmannecessary concepts to better understand use of modules in a project.
32b1d5af81SChuanqi Xu
33b1d5af81SChuanqi XuBackground and terminology
34b1d5af81SChuanqi Xu--------------------------
35b1d5af81SChuanqi Xu
36b1d5af81SChuanqi XuModule and module unit
37b1d5af81SChuanqi Xu~~~~~~~~~~~~~~~~~~~~~~
38b1d5af81SChuanqi Xu
399263318fSAaron BallmanA module consists of one or more module units. A module unit is a special kind
409263318fSAaron Ballmanof translation unit. A module unit should almost always start with a module
419263318fSAaron Ballmandeclaration. The syntax of the module declaration is:
42b1d5af81SChuanqi Xu
43b1d5af81SChuanqi Xu.. code-block:: c++
44b1d5af81SChuanqi Xu
45b1d5af81SChuanqi Xu  [export] module module_name[:partition_name];
46b1d5af81SChuanqi Xu
479263318fSAaron BallmanTerms enclosed in ``[]`` are optional. ``module_name`` and ``partition_name``
489263318fSAaron Ballmanfollow the rules for a C++ identifier, except that they may contain one or more
499263318fSAaron Ballmanperiod (``.``) characters. Note that a ``.`` in the name has no semantic
509263318fSAaron Ballmanmeaning and does not imply any hierarchy.
51b1d5af81SChuanqi Xu
529263318fSAaron BallmanIn this document, module units are classified as:
53b1d5af81SChuanqi Xu
549263318fSAaron Ballman* Primary module interface unit
559263318fSAaron Ballman* Module implementation unit
569263318fSAaron Ballman* Module partition interface unit
579263318fSAaron Ballman* Internal module partition unit
58b1d5af81SChuanqi Xu
59b1d5af81SChuanqi XuA primary module interface unit is a module unit whose module declaration is
609263318fSAaron Ballman``export module module_name;`` where ``module_name`` denotes the name of the
61b1d5af81SChuanqi Xumodule. A module should have one and only one primary module interface unit.
62b1d5af81SChuanqi Xu
63b1d5af81SChuanqi XuA module implementation unit is a module unit whose module declaration is
649263318fSAaron Ballman``module module_name;``. Multiple module implementation units can be declared
659263318fSAaron Ballmanin the same module.
66b1d5af81SChuanqi Xu
679263318fSAaron BallmanA module partition interface unit is a module unit whose module declaration is
68b1d5af81SChuanqi Xu``export module module_name:partition_name;``. The ``partition_name`` should be
69b1d5af81SChuanqi Xuunique within any given module.
70b1d5af81SChuanqi Xu
719263318fSAaron BallmanAn internal module partition unit is a module unit whose module
729263318fSAaron Ballmandeclaration is ``module module_name:partition_name;``. The ``partition_name``
739263318fSAaron Ballmanshould be unique within any given module.
74b1d5af81SChuanqi Xu
759263318fSAaron BallmanIn this document, we use the following terms:
76b1d5af81SChuanqi Xu
77b1d5af81SChuanqi Xu* A ``module interface unit`` refers to either a ``primary module interface unit``
789263318fSAaron Ballman  or a ``module partition interface unit``.
79b1d5af81SChuanqi Xu
809263318fSAaron Ballman* An ``importable module unit`` refers to either a ``module interface unit`` or
819263318fSAaron Ballman  an ``internal module partition unit``.
82b1d5af81SChuanqi Xu
839263318fSAaron Ballman* A ``module partition unit`` refers to either a ``module partition interface unit``
849263318fSAaron Ballman  or an ``internal module partition unit``.
85b1d5af81SChuanqi Xu
869263318fSAaron BallmanBuilt Module Interface
879263318fSAaron Ballman~~~~~~~~~~~~~~~~~~~~~~
88b1d5af81SChuanqi Xu
899263318fSAaron BallmanA ``Built Module Interface`` (or ``BMI``) is the precompiled result of an
909263318fSAaron Ballmanimportable module unit.
91b1d5af81SChuanqi Xu
92b1d5af81SChuanqi XuGlobal module fragment
93b1d5af81SChuanqi Xu~~~~~~~~~~~~~~~~~~~~~~
94b1d5af81SChuanqi Xu
959263318fSAaron BallmanThe ``global module fragment`` (or ``GMF``) is the code between the ``module;``
969263318fSAaron Ballmanand the module declaration within a module unit.
97b1d5af81SChuanqi Xu
98b1d5af81SChuanqi Xu
99b1d5af81SChuanqi XuHow to build projects using modules
100b1d5af81SChuanqi Xu-----------------------------------
101b1d5af81SChuanqi Xu
102b1d5af81SChuanqi XuQuick Start
103b1d5af81SChuanqi Xu~~~~~~~~~~~
104b1d5af81SChuanqi Xu
105b1d5af81SChuanqi XuLet's see a "hello world" example that uses modules.
106b1d5af81SChuanqi Xu
107b1d5af81SChuanqi Xu.. code-block:: c++
108b1d5af81SChuanqi Xu
109b1d5af81SChuanqi Xu  // Hello.cppm
110b1d5af81SChuanqi Xu  module;
111b1d5af81SChuanqi Xu  #include <iostream>
112b1d5af81SChuanqi Xu  export module Hello;
113b1d5af81SChuanqi Xu  export void hello() {
114b1d5af81SChuanqi Xu    std::cout << "Hello World!\n";
115b1d5af81SChuanqi Xu  }
116b1d5af81SChuanqi Xu
117b1d5af81SChuanqi Xu  // use.cpp
118b1d5af81SChuanqi Xu  import Hello;
119b1d5af81SChuanqi Xu  int main() {
120b1d5af81SChuanqi Xu    hello();
121b1d5af81SChuanqi Xu    return 0;
122b1d5af81SChuanqi Xu  }
123b1d5af81SChuanqi Xu
1249263318fSAaron BallmanThen, on the command line, invoke Clang like:
125b1d5af81SChuanqi Xu
126b1d5af81SChuanqi Xu.. code-block:: console
127b1d5af81SChuanqi Xu
128b1d5af81SChuanqi Xu  $ clang++ -std=c++20 Hello.cppm --precompile -o Hello.pcm
1294b99af34SChuanqi Xu  $ clang++ -std=c++20 use.cpp -fmodule-file=Hello=Hello.pcm Hello.pcm -o Hello.out
130b1d5af81SChuanqi Xu  $ ./Hello.out
131b1d5af81SChuanqi Xu  Hello World!
132b1d5af81SChuanqi Xu
133b1d5af81SChuanqi XuIn this example, we make and use a simple module ``Hello`` which contains only a
1349263318fSAaron Ballmanprimary module interface unit named ``Hello.cppm``.
135b1d5af81SChuanqi Xu
1369263318fSAaron BallmanA more complex "hello world" example which uses the 4 kinds of module units is:
137b1d5af81SChuanqi Xu
138b1d5af81SChuanqi Xu.. code-block:: c++
139b1d5af81SChuanqi Xu
140b1d5af81SChuanqi Xu  // M.cppm
141b1d5af81SChuanqi Xu  export module M;
142b1d5af81SChuanqi Xu  export import :interface_part;
143b1d5af81SChuanqi Xu  import :impl_part;
144b1d5af81SChuanqi Xu  export void Hello();
145b1d5af81SChuanqi Xu
146b1d5af81SChuanqi Xu  // interface_part.cppm
147b1d5af81SChuanqi Xu  export module M:interface_part;
148b1d5af81SChuanqi Xu  export void World();
149b1d5af81SChuanqi Xu
150b1d5af81SChuanqi Xu  // impl_part.cppm
151b1d5af81SChuanqi Xu  module;
152b1d5af81SChuanqi Xu  #include <iostream>
153b1d5af81SChuanqi Xu  #include <string>
154b1d5af81SChuanqi Xu  module M:impl_part;
155b1d5af81SChuanqi Xu  import :interface_part;
156b1d5af81SChuanqi Xu
157b1d5af81SChuanqi Xu  std::string W = "World.";
158b1d5af81SChuanqi Xu  void World() {
159b1d5af81SChuanqi Xu    std::cout << W << std::endl;
160b1d5af81SChuanqi Xu  }
161b1d5af81SChuanqi Xu
162b1d5af81SChuanqi Xu  // Impl.cpp
163b1d5af81SChuanqi Xu  module;
164b1d5af81SChuanqi Xu  #include <iostream>
165b1d5af81SChuanqi Xu  module M;
166b1d5af81SChuanqi Xu  void Hello() {
167b1d5af81SChuanqi Xu    std::cout << "Hello ";
168b1d5af81SChuanqi Xu  }
169b1d5af81SChuanqi Xu
170b1d5af81SChuanqi Xu  // User.cpp
171b1d5af81SChuanqi Xu  import M;
172b1d5af81SChuanqi Xu  int main() {
173b1d5af81SChuanqi Xu    Hello();
174b1d5af81SChuanqi Xu    World();
175b1d5af81SChuanqi Xu    return 0;
176b1d5af81SChuanqi Xu  }
177b1d5af81SChuanqi Xu
1789263318fSAaron BallmanThen, back on the command line, invoke Clang with:
179b1d5af81SChuanqi Xu
180b1d5af81SChuanqi Xu.. code-block:: console
181b1d5af81SChuanqi Xu
182b1d5af81SChuanqi Xu  # Precompiling the module
183b1d5af81SChuanqi Xu  $ clang++ -std=c++20 interface_part.cppm --precompile -o M-interface_part.pcm
184b1d5af81SChuanqi Xu  $ clang++ -std=c++20 impl_part.cppm --precompile -fprebuilt-module-path=. -o M-impl_part.pcm
185b1d5af81SChuanqi Xu  $ clang++ -std=c++20 M.cppm --precompile -fprebuilt-module-path=. -o M.pcm
1864b99af34SChuanqi Xu  $ clang++ -std=c++20 Impl.cpp -fprebuilt-module-path=. -c -o Impl.o
187b1d5af81SChuanqi Xu
188b1d5af81SChuanqi Xu  # Compiling the user
189b1d5af81SChuanqi Xu  $ clang++ -std=c++20 User.cpp -fprebuilt-module-path=. -c -o User.o
190b1d5af81SChuanqi Xu
191b1d5af81SChuanqi Xu  # Compiling the module and linking it together
1924b99af34SChuanqi Xu  $ clang++ -std=c++20 M-interface_part.pcm -fprebuilt-module-path=. -c -o M-interface_part.o
1934b99af34SChuanqi Xu  $ clang++ -std=c++20 M-impl_part.pcm -fprebuilt-module-path=. -c -o M-impl_part.o
1944b99af34SChuanqi Xu  $ clang++ -std=c++20 M.pcm -fprebuilt-module-path=. -c -o M.o
195b1d5af81SChuanqi Xu  $ clang++ User.o M-interface_part.o  M-impl_part.o M.o Impl.o -o a.out
196b1d5af81SChuanqi Xu
197b1d5af81SChuanqi XuWe explain the options in the following sections.
198b1d5af81SChuanqi Xu
199b1d5af81SChuanqi XuHow to enable standard C++ modules
200b1d5af81SChuanqi Xu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
201b1d5af81SChuanqi Xu
2029263318fSAaron BallmanStandard C++ modules are enabled automatically when the language standard mode
2039263318fSAaron Ballmanis ``-std=c++20`` or newer.
204b1d5af81SChuanqi Xu
205b1d5af81SChuanqi XuHow to produce a BMI
206b1d5af81SChuanqi Xu~~~~~~~~~~~~~~~~~~~~
207b1d5af81SChuanqi Xu
2089263318fSAaron BallmanTo generate a BMI for an importable module unit, use either the ``--precompile``
2099263318fSAaron Ballmanor ``-fmodule-output`` command line options.
210046a9910SChuanqi Xu
2119263318fSAaron BallmanThe ``--precompile`` option generates the BMI as the output of the compilation
2129263318fSAaron Ballmanwith the output path specified using the ``-o`` option.
213046a9910SChuanqi Xu
2149263318fSAaron BallmanThe ``-fmodule-output`` option generates the BMI as a by-product of the
2159263318fSAaron Ballmancompilation. If ``-fmodule-output=`` is specified, the BMI will be emitted to
2169263318fSAaron Ballmanthe specified location. If ``-fmodule-output`` and ``-c`` are specified, the
2179263318fSAaron BallmanBMI will be emitted in the directory of the output file with the name of the
2189263318fSAaron Ballmaninput file with the extension ``.pcm``. Otherwise, the BMI will be emitted in
2199263318fSAaron Ballmanthe working directory with the name of the input file with the extension
220046a9910SChuanqi Xu``.pcm``.
221046a9910SChuanqi Xu
2229263318fSAaron BallmanGenerating BMIs with ``--precompile`` is referred to as two-phase compilation
2239263318fSAaron Ballmanbecause it takes two steps to compile a source file to an object file.
2249263318fSAaron BallmanGenerating BMIs with ``-fmodule-output`` is called one-phase compilation. The
2259263318fSAaron Ballmanone-phase compilation model is simpler for build systems to implement while the
2269263318fSAaron Ballmantwo-phase compilation has the potential to compile faster due to higher
2279263318fSAaron Ballmanparallelism. As an example, if there are two module units ``A`` and ``B``, and
2289263318fSAaron Ballman``B`` depends on ``A``, the one-phase compilation model needs to compile them
2299263318fSAaron Ballmanserially, whereas the two-phase compilation model is able to be compiled as
2309263318fSAaron Ballmansoon as ``A.pcm`` is available, and thus can be compiled simultaneously as the
2319263318fSAaron Ballman``A.pcm`` to ``A.o`` compilation step.
232b1d5af81SChuanqi Xu
2339263318fSAaron BallmanFile name requirements
2349263318fSAaron Ballman~~~~~~~~~~~~~~~~~~~~~~
235b1d5af81SChuanqi Xu
2369263318fSAaron BallmanBy convention, ``importable module unit`` files should use ``.cppm`` (or
2379263318fSAaron Ballman``.ccm``, ``.cxxm``, or ``.c++m``) as a file extension.
2389263318fSAaron Ballman``Module implementation unit`` files should use ``.cpp`` (or ``.cc``, ``.cxx``,
2399263318fSAaron Ballmanor ``.c++``) as a file extension.
240b1d5af81SChuanqi Xu
2419263318fSAaron BallmanA BMI should use ``.pcm`` as a file extension. The file name of the BMI for a
2429263318fSAaron Ballman``primary module interface unit`` should be ``module_name.pcm``. The file name
2439263318fSAaron Ballmanof a BMI for a ``module partition unit`` should be
2449263318fSAaron Ballman``module_name-partition_name.pcm``.
245b1d5af81SChuanqi Xu
2469263318fSAaron BallmanClang may fail to build the module if different extensions are used. For
2479263318fSAaron Ballmanexample, if the filename of an ``importable module unit`` ends with ``.cpp``
2489263318fSAaron Ballmaninstead of ``.cppm``, then Clang cannot generate a BMI for the
2499263318fSAaron Ballman``importable module unit`` with the ``--precompile`` option because the
2509263318fSAaron Ballman``--precompile`` option would only run the preprocessor (``-E``). If using a
2519263318fSAaron Ballmandifferent extension than the conventional one for an ``importable module unit``
2529263318fSAaron Ballmanyou can specify ``-x c++-module`` before the file. For example,
253b1d5af81SChuanqi Xu
254b1d5af81SChuanqi Xu.. code-block:: c++
255b1d5af81SChuanqi Xu
256b1d5af81SChuanqi Xu  // Hello.cpp
257b1d5af81SChuanqi Xu  module;
258b1d5af81SChuanqi Xu  #include <iostream>
259b1d5af81SChuanqi Xu  export module Hello;
260b1d5af81SChuanqi Xu  export void hello() {
261b1d5af81SChuanqi Xu    std::cout << "Hello World!\n";
262b1d5af81SChuanqi Xu  }
263b1d5af81SChuanqi Xu
264b1d5af81SChuanqi Xu  // use.cpp
265b1d5af81SChuanqi Xu  import Hello;
266b1d5af81SChuanqi Xu  int main() {
267b1d5af81SChuanqi Xu    hello();
268b1d5af81SChuanqi Xu    return 0;
269b1d5af81SChuanqi Xu  }
270b1d5af81SChuanqi Xu
2719263318fSAaron BallmanIn this example, the extension used by the ``module interface`` is ``.cpp``
2729263318fSAaron Ballmaninstead of ``.cppm``, so it cannot be compiled like the previous example, but
2739263318fSAaron Ballmanit can be compiled with:
274b1d5af81SChuanqi Xu
275b1d5af81SChuanqi Xu.. code-block:: console
276b1d5af81SChuanqi Xu
277b1d5af81SChuanqi Xu  $ clang++ -std=c++20 -x c++-module Hello.cpp --precompile -o Hello.pcm
278b1d5af81SChuanqi Xu  $ clang++ -std=c++20 use.cpp -fprebuilt-module-path=. Hello.pcm -o Hello.out
279b1d5af81SChuanqi Xu  $ ./Hello.out
280b1d5af81SChuanqi Xu  Hello World!
281b1d5af81SChuanqi Xu
2829263318fSAaron BallmanModule name requirements
2839263318fSAaron Ballman~~~~~~~~~~~~~~~~~~~~~~~~
28404fb3e3dSChuanqi Xu
2859263318fSAaron Ballman..
28604fb3e3dSChuanqi Xu
2879263318fSAaron Ballman  [module.unit]p1:
288de034cf3SChuanqi Xu
289de034cf3SChuanqi Xu  All module-names either beginning with an identifier consisting of std followed by zero
29004fb3e3dSChuanqi Xu  or more digits or containing a reserved identifier ([lex.name]) are reserved and shall not
29104fb3e3dSChuanqi Xu  be specified in a module-declaration; no diagnostic is required. If any identifier in a reserved
29204fb3e3dSChuanqi Xu  module-name is a reserved identifier, the module name is reserved for use by C++ implementations;
29304fb3e3dSChuanqi Xu  otherwise it is reserved for future standardization.
29404fb3e3dSChuanqi Xu
2959263318fSAaron BallmanTherefore, none of the following names are valid by default:
29604fb3e3dSChuanqi Xu
29704fb3e3dSChuanqi Xu.. code-block:: text
29804fb3e3dSChuanqi Xu
29904fb3e3dSChuanqi Xu    std
30004fb3e3dSChuanqi Xu    std1
30104fb3e3dSChuanqi Xu    std.foo
30204fb3e3dSChuanqi Xu    __test
30304fb3e3dSChuanqi Xu    // and so on ...
30404fb3e3dSChuanqi Xu
3059263318fSAaron BallmanUsing a reserved module name is strongly discouraged, but
3069263318fSAaron Ballman``-Wno-reserved-module-identifier`` can be used to suppress the warning.
30704fb3e3dSChuanqi Xu
3089263318fSAaron BallmanSpecifying dependent BMIs
3099263318fSAaron Ballman~~~~~~~~~~~~~~~~~~~~~~~~~
310b1d5af81SChuanqi Xu
3119263318fSAaron BallmanThere are 3 ways to specify a dependent BMI:
3121782e8f9SChuanqi Xu
3139263318fSAaron Ballman1. ``-fprebuilt-module-path=<path/to/directory>``.
3149263318fSAaron Ballman2. ``-fmodule-file=<path/to/BMI>`` (Deprecated).
3159263318fSAaron Ballman3. ``-fmodule-file=<module-name>=<path/to/BMI>``.
3161782e8f9SChuanqi Xu
3179263318fSAaron BallmanThe ``-fprebuilt-module-path`` option specifies the path to search for
3189263318fSAaron Ballmandependent BMIs. Multiple paths may be specified, similar to using ``-I`` to
3199263318fSAaron Ballmanspecify a search path for header files. When importing a module ``M``, the
3209263318fSAaron Ballmancompiler looks for ``M.pcm`` in the directories specified by
3219263318fSAaron Ballman``-fprebuilt-module-path``. Similarly, when importing a partition module unit
3229263318fSAaron Ballman``M:P``, the compiler looks for ``M-P.pcm`` in the directories specified by
3239263318fSAaron Ballman``-fprebuilt-module-path``.
324b1d5af81SChuanqi Xu
3259263318fSAaron BallmanThe ``-fmodule-file=<path/to/BMI>`` option causes the compiler to load the
3269263318fSAaron Ballmanspecified BMI directly. The ``-fmodule-file=<module-name>=<path/to/BMI>``
3279263318fSAaron Ballmanoption causes the compiler to load the specified BMI for the module specified
3289263318fSAaron Ballmanby ``<module-name>`` when necessary. The main difference is that
3291782e8f9SChuanqi Xu``-fmodule-file=<path/to/BMI>`` will load the BMI eagerly, whereas
3309263318fSAaron Ballman``-fmodule-file=<module-name>=<path/to/BMI>`` will only load the BMI lazily,
3319263318fSAaron Ballmanas will ``-fprebuilt-module-path``. The ``-fmodule-file=<path/to/BMI>`` option
3329263318fSAaron Ballmanfor named modules is deprecated and will be removed in a future version of
3339263318fSAaron BallmanClang.
334b1d5af81SChuanqi Xu
3359263318fSAaron BallmanWhen these options are specified in the same invocation of the compiler, the
3369263318fSAaron Ballman``-fmodule-file=<path/to/BMI>`` option takes precedence over
3379263318fSAaron Ballman``-fmodule-file=<module-name>=<path/to/BMI>``, which takes precedence over
3389263318fSAaron Ballman``-fprebuilt-module-path=<path/to/directory>``.
3391782e8f9SChuanqi Xu
3409263318fSAaron BallmanNote: all dependant BMIs must be specified explicitly, either directly or
3419263318fSAaron Ballmanindirectly dependent BMIs explicitly. See
3429263318fSAaron Ballmanhttps://github.com/llvm/llvm-project/issues/62707 for details.
343a31a6007SChuanqi Xu
3449263318fSAaron BallmanWhen compiling a ``module implementation unit``, the BMI of the corresponding
3459263318fSAaron Ballman``primary module interface unit`` must be specified because a module
3469263318fSAaron Ballmanimplementation unit implicitly imports the primary module interface unit.
347b1d5af81SChuanqi Xu
348b1d5af81SChuanqi Xu  [module.unit]p8
349b1d5af81SChuanqi Xu
350b1d5af81SChuanqi Xu  A module-declaration that contains neither an export-keyword nor a module-partition implicitly
351b1d5af81SChuanqi Xu  imports the primary module interface unit of the module as if by a module-import-declaration.
352b1d5af81SChuanqi Xu
3539263318fSAaron BallmanThe ``-fprebuilt-module-path=<path/to/directory>``, ``-fmodule-file=<path/to/BMI>``,
3549263318fSAaron Ballmanand ``-fmodule-file=<module-name>=<path/to/BMI>`` options may be specified
3559263318fSAaron Ballmanmultiple times. For example, the command line to compile ``M.cppm`` in
3569263318fSAaron Ballmanthe previous example could be rewritten as:
357b1d5af81SChuanqi Xu
358b1d5af81SChuanqi Xu.. code-block:: console
359b1d5af81SChuanqi Xu
3601782e8f9SChuanqi Xu  $ clang++ -std=c++20 M.cppm --precompile -fmodule-file=M:interface_part=M-interface_part.pcm -fmodule-file=M:impl_part=M-impl_part.pcm -o M.pcm
361b1d5af81SChuanqi Xu
36222043643SChuanqi XuWhen there are multiple ``-fmodule-file=<module-name>=`` options for the same
3639263318fSAaron Ballman``<module-name>``, the last ``-fmodule-file=<module-name>=`` overrides the
3649263318fSAaron Ballmanprevious ``-fmodule-file=<module-name>=`` option.
365b1d5af81SChuanqi Xu
366b1d5af81SChuanqi XuRemember that module units still have an object counterpart to the BMI
367b1d5af81SChuanqi Xu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
368b1d5af81SChuanqi Xu
3699263318fSAaron BallmanWhile module interfaces resemble traditional header files, they still require
3709263318fSAaron Ballmancompilation. Module units are translation units, and need to be compiled to
3719263318fSAaron Ballmanobject files, which then need to be linked together as the following examples
3729263318fSAaron Ballmanshow.
373b1d5af81SChuanqi Xu
374b1d5af81SChuanqi XuFor example, the traditional compilation processes for headers are like:
375b1d5af81SChuanqi Xu
376b1d5af81SChuanqi Xu.. code-block:: text
377b1d5af81SChuanqi Xu
378b1d5af81SChuanqi Xu  src1.cpp -+> clang++ src1.cpp --> src1.o ---,
379b1d5af81SChuanqi Xu  hdr1.h  --'                                 +-> clang++ src1.o src2.o ->  executable
380b1d5af81SChuanqi Xu  hdr2.h  --,                                 |
381b1d5af81SChuanqi Xu  src2.cpp -+> clang++ src2.cpp --> src2.o ---'
382b1d5af81SChuanqi Xu
383b1d5af81SChuanqi XuAnd the compilation process for module units are like:
384b1d5af81SChuanqi Xu
385b1d5af81SChuanqi Xu.. code-block:: text
386b1d5af81SChuanqi Xu
387b1d5af81SChuanqi Xu                src1.cpp ----------------------------------------+> clang++ src1.cpp -------> src1.o -,
388b1d5af81SChuanqi Xu  (header unit) hdr1.h    -> clang++ hdr1.h ...    -> hdr1.pcm --'                                    +-> clang++ src1.o mod1.o src2.o ->  executable
389b1d5af81SChuanqi Xu                mod1.cppm -> clang++ mod1.cppm ... -> mod1.pcm --,--> clang++ mod1.pcm ... -> mod1.o -+
390b1d5af81SChuanqi Xu                src2.cpp ----------------------------------------+> clang++ src2.cpp -------> src2.o -'
391b1d5af81SChuanqi Xu
3929263318fSAaron BallmanAs the diagrams show, we need to compile the BMI from module units to object
3939263318fSAaron Ballmanfiles and then link the object files. (However, this cannot be done for the BMI
3949263318fSAaron Ballmanfrom header units. See the section on :ref:`header units <header-units>` for
3959263318fSAaron Ballmanmore details.
396b1d5af81SChuanqi Xu
3979263318fSAaron BallmanBMIs cannot be shipped in an archive to create a module library. Instead, the
3989263318fSAaron BallmanBMIs(``*.pcm``) are compiled into object files(``*.o``) and those object files
3999263318fSAaron Ballmanare added to the archive instead.
400b1d5af81SChuanqi Xu
401bd576fe3SSharadh Rajaramanclang-cl
402bd576fe3SSharadh Rajaraman~~~~~~~~
403bd576fe3SSharadh Rajaraman
404bd576fe3SSharadh Rajaraman``clang-cl`` supports the same options as ``clang++`` for modules as detailed above;
405bd576fe3SSharadh Rajaramanthere is no need to prefix these options with ``/clang:``. Note that ``cl.exe``
406bd576fe3SSharadh Rajaraman`options to emit/consume IFC files <https://devblogs.microsoft.com/cppblog/using-cpp-modules-in-msvc-from-the-command-line-part-1/>` are *not* supported.
407bd576fe3SSharadh RajaramanThe resultant precompiled modules are also not compatible for use with ``cl.exe``.
408bd576fe3SSharadh Rajaraman
409bd576fe3SSharadh RajaramanWe recommend that build system authors use the above-mentioned ``clang++`` options  with ``clang-cl`` to build modules.
410bd576fe3SSharadh Rajaraman
4119263318fSAaron BallmanConsistency Requirements
4129263318fSAaron Ballman~~~~~~~~~~~~~~~~~~~~~~~~
413b1d5af81SChuanqi Xu
4149263318fSAaron BallmanModules can be viewed as a kind of cache to speed up compilation. Thus, like
4159263318fSAaron Ballmanother caching techniques, it is important to maintain cache consistency which
4169263318fSAaron Ballmanis why Clang does very strict checking for consistency.
417b1d5af81SChuanqi Xu
418b1d5af81SChuanqi XuOptions consistency
419b1d5af81SChuanqi Xu^^^^^^^^^^^^^^^^^^^
420b1d5af81SChuanqi Xu
4219263318fSAaron BallmanCompiler options related to the language dialect for a module unit and its
4229263318fSAaron Ballmannon-module-unit uses need to be consistent. Consider the following example:
423b1d5af81SChuanqi Xu
424b1d5af81SChuanqi Xu.. code-block:: c++
425b1d5af81SChuanqi Xu
426b1d5af81SChuanqi Xu  // M.cppm
427b1d5af81SChuanqi Xu  export module M;
428b1d5af81SChuanqi Xu
429b1d5af81SChuanqi Xu  // Use.cpp
430b1d5af81SChuanqi Xu  import M;
431b1d5af81SChuanqi Xu
432b1d5af81SChuanqi Xu.. code-block:: console
433b1d5af81SChuanqi Xu
434b1d5af81SChuanqi Xu  $ clang++ -std=c++20 M.cppm --precompile -o M.pcm
435ba15d186SMark de Wever  $ clang++ -std=c++23 Use.cpp -fprebuilt-module-path=.
436b1d5af81SChuanqi Xu
4379263318fSAaron BallmanClang rejects the example due to the inconsistent language standard modes. Not
4389263318fSAaron Ballmanall compiler options are language dialect options, though. For example:
439b1d5af81SChuanqi Xu
440b1d5af81SChuanqi Xu.. code-block:: console
441b1d5af81SChuanqi Xu
442b1d5af81SChuanqi Xu  $ clang++ -std=c++20 M.cppm --precompile -o M.pcm
443b1d5af81SChuanqi Xu  # Inconsistent optimization level.
444b1d5af81SChuanqi Xu  $ clang++ -std=c++20 -O3 Use.cpp -fprebuilt-module-path=.
445b1d5af81SChuanqi Xu  # Inconsistent debugging level.
446b1d5af81SChuanqi Xu  $ clang++ -std=c++20 -g Use.cpp -fprebuilt-module-path=.
447b1d5af81SChuanqi Xu
4489263318fSAaron BallmanAlthough the optimization and debugging levels are inconsistent, these
4499263318fSAaron Ballmancompilations are accepted because the compiler options do not impact the
4509263318fSAaron Ballmanlanguage dialect.
451b1d5af81SChuanqi Xu
4529263318fSAaron BallmanNote that the compiler **currently** doesn't reject inconsistent macro
4539263318fSAaron Ballmandefinitions (this may change in the future). For example:
454b1d5af81SChuanqi Xu
455b1d5af81SChuanqi Xu.. code-block:: console
456b1d5af81SChuanqi Xu
457b1d5af81SChuanqi Xu  $ clang++ -std=c++20 M.cppm --precompile -o M.pcm
458b1d5af81SChuanqi Xu  # Inconsistent optimization level.
459b1d5af81SChuanqi Xu  $ clang++ -std=c++20 -O3 -DNDEBUG Use.cpp -fprebuilt-module-path=.
460b1d5af81SChuanqi Xu
4619263318fSAaron BallmanCurrently, Clang accepts the above example, though it may produce surprising
4629263318fSAaron Ballmanresults if the debugging code depends on consistent use of ``NDEBUG`` in other
4639263318fSAaron Ballmantranslation units.
464b1d5af81SChuanqi Xu
465f41f6ea1SChuanqi XuSource Files Consistency
466f41f6ea1SChuanqi Xu^^^^^^^^^^^^^^^^^^^^^^^^
467f41f6ea1SChuanqi Xu
468f41f6ea1SChuanqi XuClang may open the input files\ :sup:`1`` of a BMI during the compilation. This implies that
469f41f6ea1SChuanqi Xuwhen Clang consumes a BMI, all the input files need to be present in the original path
470f41f6ea1SChuanqi Xuand with the original contents.
471f41f6ea1SChuanqi Xu
472f41f6ea1SChuanqi XuTo overcome these requirements and simplify cases like distributed builds and sandboxed
473f41f6ea1SChuanqi Xubuilds, users can use the ``-fmodules-embed-all-files`` flag to embed all input files
474f41f6ea1SChuanqi Xuinto the BMI so that Clang does not need to open the corresponding file on disk.
475f41f6ea1SChuanqi Xu
476f41f6ea1SChuanqi XuWhen the ``-fmodules-embed-all-files`` flag are enabled, Clang explicitly emits the source
477f41f6ea1SChuanqi Xucode into the BMI file, the contents of the BMI file contain a sufficiently verbose
478f41f6ea1SChuanqi Xurepresentation to reproduce the original source file.
479f41f6ea1SChuanqi Xu
480f41f6ea1SChuanqi Xu:sup:`1`` Input files: The source files which took part in the compilation of the BMI.
481f41f6ea1SChuanqi XuFor example:
482f41f6ea1SChuanqi Xu
483f41f6ea1SChuanqi Xu.. code-block:: c++
484f41f6ea1SChuanqi Xu
485f41f6ea1SChuanqi Xu  // M.cppm
486f41f6ea1SChuanqi Xu  module;
487f41f6ea1SChuanqi Xu  #include "foo.h"
488f41f6ea1SChuanqi Xu  export module M;
489f41f6ea1SChuanqi Xu
490f41f6ea1SChuanqi Xu  // foo.h
491f41f6ea1SChuanqi Xu  #pragma once
492f41f6ea1SChuanqi Xu  #include "bar.h"
493f41f6ea1SChuanqi Xu
494f41f6ea1SChuanqi XuThe ``M.cppm``, ``foo.h`` and ``bar.h`` are input files for the BMI of ``M.cppm``.
495f41f6ea1SChuanqi Xu
4969263318fSAaron BallmanObject definition consistency
4979263318fSAaron Ballman^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4988eea582dSChuanqi Xu
4999263318fSAaron BallmanThe C++ language requires that declarations of the same entity in different
5009263318fSAaron Ballmantranslation units have the same definition, which is known as the One
5019263318fSAaron BallmanDefinition Rule (ODR). Without modules, the compiler cannot perform strong ODR
5029263318fSAaron Ballmanviolation checking because it only sees one translation unit at a time. With
5039263318fSAaron Ballmanthe use of modules, the compiler can perform checks for ODR violations across
5049263318fSAaron Ballmantranslation units.
5058eea582dSChuanqi Xu
5069263318fSAaron BallmanHowever, the current ODR checking mechanisms are not perfect. There are a
5079263318fSAaron Ballmansignificant number of false positive ODR violation diagnostics, where the
5089263318fSAaron Ballmancompiler incorrectly diagnoses two identical declarations as having different
5099263318fSAaron Ballmandefinitions. Further, true positive ODR violations are not always reported.
5108eea582dSChuanqi Xu
5119263318fSAaron BallmanTo give a better user experience, improve compilation performance, and for
5129263318fSAaron Ballmanconsistency with MSVC, ODR checking of declarations in the global module
5139263318fSAaron Ballmanfragment is disabled by default. These checks can be enabled by specifying
5149263318fSAaron Ballman``-Xclang -fno-skip-odr-check-in-gmf`` when compiling. If the check is enabled
5159263318fSAaron Ballmanand you encounter incorrect or missing diagnostics, please report them via the
5169263318fSAaron Ballman`community issue tracker <https://github.com/llvm/llvm-project/issues/>`_.
5178eea582dSChuanqi Xu
518f41f6ea1SChuanqi XuPrivacy Issue
519f41f6ea1SChuanqi Xu-------------
520f41f6ea1SChuanqi Xu
521f41f6ea1SChuanqi XuBMIs are not and should not be treated as an information hiding mechanism.
522f41f6ea1SChuanqi XuThey should always be assumed to contain all the information that was used to
523f41f6ea1SChuanqi Xucreate them, in a recoverable form.
524f41f6ea1SChuanqi Xu
525b1d5af81SChuanqi XuABI Impacts
526b1d5af81SChuanqi Xu-----------
527b1d5af81SChuanqi Xu
5289263318fSAaron BallmanThis section describes the new ABI changes brought by modules. Only changes to
5299263318fSAaron Ballmanthe Itanium C++ ABI are covered.
530e7a8dd9bSChuanqi Xu
5319263318fSAaron BallmanName Mangling
5329263318fSAaron Ballman~~~~~~~~~~~~~
533e7a8dd9bSChuanqi Xu
5349263318fSAaron BallmanThe declarations in a module unit which are not in the global module fragment
5359263318fSAaron Ballmanhave new linkage names.
536b1d5af81SChuanqi Xu
537b1d5af81SChuanqi XuFor example,
538b1d5af81SChuanqi Xu
539b1d5af81SChuanqi Xu.. code-block:: c++
540b1d5af81SChuanqi Xu
541b1d5af81SChuanqi Xu  export module M;
542b1d5af81SChuanqi Xu  namespace NS {
543b1d5af81SChuanqi Xu    export int foo();
544b1d5af81SChuanqi Xu  }
545b1d5af81SChuanqi Xu
5469263318fSAaron BallmanThe linkage name of ``NS::foo()`` is ``_ZN2NSW1M3fooEv``. This couldn't be
5479263318fSAaron Ballmandemangled by previous versions of the debugger or demangler. As of LLVM 15.x,
5489263318fSAaron Ballman``llvm-cxxfilt`` can be used to demangle this:
549b1d5af81SChuanqi Xu
550b1d5af81SChuanqi Xu.. code-block:: console
551b1d5af81SChuanqi Xu
552b1d5af81SChuanqi Xu  $ llvm-cxxfilt _ZN2NSW1M3fooEv
5539263318fSAaron Ballman    NS::foo@M()
554b1d5af81SChuanqi Xu
5559263318fSAaron BallmanThe result should be read as ``NS::foo()`` in module ``M``.
556b1d5af81SChuanqi Xu
5579263318fSAaron BallmanThe ABI implies that something cannot be declared in a module unit and defined
5589263318fSAaron Ballmanin a non-module unit (or vice-versa), as this would result in linking errors.
559b1d5af81SChuanqi Xu
5609263318fSAaron BallmanDespite this, it is possible to implement declarations with a compatible ABI in
5619263318fSAaron Ballmana module unit by using a language linkage specifier because the declarations in
5629263318fSAaron Ballmanthe language linkage specifier are attached to the global module fragment. For
5639263318fSAaron Ballmanexample:
564e264fe89SChuanqi Xu
565e264fe89SChuanqi Xu.. code-block:: c++
566e264fe89SChuanqi Xu
567e264fe89SChuanqi Xu  export module M;
568e264fe89SChuanqi Xu  namespace NS {
569e264fe89SChuanqi Xu    export extern "C++" int foo();
570e264fe89SChuanqi Xu  }
571e264fe89SChuanqi Xu
572e264fe89SChuanqi XuNow the linkage name of ``NS::foo()`` will be ``_ZN2NS3fooEv``.
573e264fe89SChuanqi Xu
574e7a8dd9bSChuanqi XuModule Initializers
575e7a8dd9bSChuanqi Xu~~~~~~~~~~~~~~~~~~~
576e7a8dd9bSChuanqi Xu
5779263318fSAaron BallmanAll importable module units are required to emit an initializer function to
5789263318fSAaron Ballmanhandle the dynamic initialization of non-inline variables in the module unit.
5799263318fSAaron BallmanThe importable module unit has to emit the initializer even if there is no
5809263318fSAaron Ballmandynamic initialization; otherwise, the importer may call a nonexistent
5819263318fSAaron Ballmanfunction. The initializer function emits calls to imported modules first
5829263318fSAaron Ballmanfollowed by calls to all to of the dynamic initializers in the current module
5839263318fSAaron Ballmanunit.
584e7a8dd9bSChuanqi Xu
5859263318fSAaron BallmanTranslation units that explicitly or implicitly import a named module must call
5869263318fSAaron Ballmanthe initializer functions of the imported named module within the sequence of
5879263318fSAaron Ballmanthe dynamic initializers in the translation unit. Initializations of entities
5889263318fSAaron Ballmanat namespace scope are appearance-ordered. This (recursively) extends to
5899263318fSAaron Ballmanimported modules at the point of appearance of the import declaration.
590e7a8dd9bSChuanqi Xu
5919263318fSAaron BallmanIf the imported module is known to be empty, the call to its initializer may be
5929263318fSAaron Ballmanomitted. Additionally, if the imported module is known to have already been
5939263318fSAaron Ballmanimported, the call to its initializer may be omitted.
594e7a8dd9bSChuanqi Xu
595e6ecff8dSChuanqi XuReduced BMI
596e6ecff8dSChuanqi Xu-----------
597e6ecff8dSChuanqi Xu
5989263318fSAaron BallmanTo support the two-phase compilation model, Clang puts everything needed to
5999263318fSAaron Ballmanproduce an object into the BMI. However, other consumers of the BMI generally
6009263318fSAaron Ballmandon't need that information. This makes the BMI larger and may introduce
6019263318fSAaron Ballmanunnecessary dependencies for the BMI. To mitigate the problem, Clang has a
6029263318fSAaron Ballmancompiler option to reduce the information contained in the BMI. These two
6039263318fSAaron Ballmanformats are known as Full BMI and Reduced BMI, respectively.
604e6ecff8dSChuanqi Xu
605*411196b9SChuanqi XuUsers can use the ``-fmodules-reduced-bmi`` option to produce a
6069263318fSAaron BallmanReduced BMI.
607e6ecff8dSChuanqi Xu
6089263318fSAaron BallmanFor the one-phase compilation model (CMake implements this model), with
609*411196b9SChuanqi Xu``-fmodules-reduced-bmi``, the generated BMI will be a Reduced
6109263318fSAaron BallmanBMI automatically. (The output path of the BMI is specified by
6119263318fSAaron Ballman``-fmodule-output=`` as usual with the one-phase compilation model).
612e6ecff8dSChuanqi Xu
6139263318fSAaron BallmanIt is also possible to produce a Reduced BMI with the two-phase compilation
614*411196b9SChuanqi Xumodel. When ``-fmodules-reduced-bmi``, ``--precompile``, and
6159263318fSAaron Ballman``-fmodule-output=`` are specified, the generated BMI specified by ``-o`` will
6169263318fSAaron Ballmanbe a full BMI and the BMI specified by ``-fmodule-output=`` will be a Reduced
6179263318fSAaron BallmanBMI. The dependency graph in this case would look like:
618e6ecff8dSChuanqi Xu
619e6ecff8dSChuanqi Xu.. code-block:: none
620e6ecff8dSChuanqi Xu
621e6ecff8dSChuanqi Xu  module-unit.cppm --> module-unit.full.pcm -> module-unit.o
622e6ecff8dSChuanqi Xu                    |
623e6ecff8dSChuanqi Xu                    -> module-unit.reduced.pcm -> consumer1.cpp
624e6ecff8dSChuanqi Xu                                               -> consumer2.cpp
625e6ecff8dSChuanqi Xu                                               -> ...
626e6ecff8dSChuanqi Xu                                               -> consumer_n.cpp
627e6ecff8dSChuanqi Xu
628*411196b9SChuanqi XuClang does not emit diagnostics when ``-fmodules-reduced-bmi`` is
6299263318fSAaron Ballmanused with a non-module unit. This design permits users of the one-phase
6309263318fSAaron Ballmancompilation model to try using reduced BMIs without needing to modify the build
6319263318fSAaron Ballmansystem. The two-phase compilation module requires build system support.
632e6ecff8dSChuanqi Xu
6339263318fSAaron BallmanIn a Reduced BMI, Clang does not emit unreachable entities from the global
6349263318fSAaron Ballmanmodule fragment, or definitions of non-inline functions and non-inline
6359263318fSAaron Ballmanvariables. This may not be a transparent change.
6369263318fSAaron Ballman
6379263318fSAaron BallmanConsider the following example:
638e6ecff8dSChuanqi Xu
639e6ecff8dSChuanqi Xu.. code-block:: c++
640e6ecff8dSChuanqi Xu
641e6ecff8dSChuanqi Xu  // foo.h
642e6ecff8dSChuanqi Xu  namespace N {
643e6ecff8dSChuanqi Xu    struct X {};
644e6ecff8dSChuanqi Xu    int d();
645e6ecff8dSChuanqi Xu    int e();
646e6ecff8dSChuanqi Xu    inline int f(X, int = d()) { return e(); }
647e6ecff8dSChuanqi Xu    int g(X);
648e6ecff8dSChuanqi Xu    int h(X);
649e6ecff8dSChuanqi Xu  }
650e6ecff8dSChuanqi Xu
651e6ecff8dSChuanqi Xu  // M.cppm
652e6ecff8dSChuanqi Xu  module;
653e6ecff8dSChuanqi Xu  #include "foo.h"
654e6ecff8dSChuanqi Xu  export module M;
655e6ecff8dSChuanqi Xu  template<typename T> int use_f() {
656e6ecff8dSChuanqi Xu    N::X x;                       // N::X, N, and :: are decl-reachable from use_f
657e6ecff8dSChuanqi Xu    return f(x, 123);             // N::f is decl-reachable from use_f,
658e6ecff8dSChuanqi Xu                                  // N::e is indirectly decl-reachable from use_f
659e6ecff8dSChuanqi Xu                                  //   because it is decl-reachable from N::f, and
660e6ecff8dSChuanqi Xu                                  // N::d is decl-reachable from use_f
661e6ecff8dSChuanqi Xu                                  //   because it is decl-reachable from N::f
662e6ecff8dSChuanqi Xu                                  //   even though it is not used in this call
663e6ecff8dSChuanqi Xu  }
664e6ecff8dSChuanqi Xu  template<typename T> int use_g() {
665e6ecff8dSChuanqi Xu    N::X x;                       // N::X, N, and :: are decl-reachable from use_g
666e6ecff8dSChuanqi Xu    return g((T(), x));           // N::g is not decl-reachable from use_g
667e6ecff8dSChuanqi Xu  }
668e6ecff8dSChuanqi Xu  template<typename T> int use_h() {
669e6ecff8dSChuanqi Xu    N::X x;                       // N::X, N, and :: are decl-reachable from use_h
670e6ecff8dSChuanqi Xu    return h((T(), x));           // N::h is not decl-reachable from use_h, but
671e6ecff8dSChuanqi Xu                                  // N::h is decl-reachable from use_h<int>
672e6ecff8dSChuanqi Xu  }
673e6ecff8dSChuanqi Xu  int k = use_h<int>();
674e6ecff8dSChuanqi Xu    // use_h<int> is decl-reachable from k, so
675e6ecff8dSChuanqi Xu    // N::h is decl-reachable from k
676e6ecff8dSChuanqi Xu
677e6ecff8dSChuanqi Xu  // M-impl.cpp
678e6ecff8dSChuanqi Xu  module M;
679e6ecff8dSChuanqi Xu  int a = use_f<int>();           // OK
680e6ecff8dSChuanqi Xu  int b = use_g<int>();           // error: no viable function for call to g;
681e6ecff8dSChuanqi Xu                                  // g is not decl-reachable from purview of
682e6ecff8dSChuanqi Xu                                  // module M's interface, so is discarded
683e6ecff8dSChuanqi Xu  int c = use_h<int>();           // OK
684e6ecff8dSChuanqi Xu
6859263318fSAaron BallmanIn the above example, the function definition of ``N::g`` is elided from the
6869263318fSAaron BallmanReduced BMI of ``M.cppm``. Then the use of ``use_g<int>`` in ``M-impl.cpp``
6879263318fSAaron Ballmanfails to instantiate. For such issues, users can add references to ``N::g`` in
6889263318fSAaron Ballmanthe `module purview <https://eel.is/c++draft/module.unit#5>`_ of ``M.cppm`` to
6899263318fSAaron Ballmanensure it is reachable, e.g. ``using N::g;``.
690e6ecff8dSChuanqi Xu
6919263318fSAaron BallmanSupport for Reduced BMIs is still experimental, but it may become the default
6929263318fSAaron Ballmanin the future. The expected roadmap for Reduced BMIs as of Clang 19.x is:
693e6ecff8dSChuanqi Xu
694*411196b9SChuanqi Xu1. ``-fexperimental-modules-reduced-bmi`` was introduced in v19.x
695*411196b9SChuanqi Xu2. For v20.x, ``-fmodules-reduced-bmi`` is introduced as an equivalent non-experimental
696*411196b9SChuanqi Xu   option. It is expected to stay opt-in for 1~2 releases, though the period depends
6979263318fSAaron Ballman   on user feedback and may be extended.
6989263318fSAaron Ballman3. Finally, ``-fmodules-reduced-bmi`` will be the default. When that time
6999263318fSAaron Ballman   comes, the term BMI will refer to the Reduced BMI and the Full BMI will only
7009263318fSAaron Ballman   be meaningful to build systems which elect to support two-phase compilation.
701e6ecff8dSChuanqi Xu
7026f710fefSChuanqi XuExperimental Non-Cascading Changes
7036f710fefSChuanqi Xu----------------------------------
7046f710fefSChuanqi Xu
7056f710fefSChuanqi XuThis section is primarily for build system vendors. For end compiler users,
7066f710fefSChuanqi Xuif you don't want to read it all, this is helpful to reduce recompilations.
7076f710fefSChuanqi XuWe encourage build system vendors and end users try this out and bring feedback.
7086f710fefSChuanqi Xu
7096f710fefSChuanqi XuBefore Clang 19, a change in BMI of any (transitive) dependency would cause the
7106f710fefSChuanqi Xuoutputs of the BMI to change. Starting with Clang 19, changes to non-direct
7116f710fefSChuanqi Xudependencies should not directly affect the output BMI, unless they affect the
7126f710fefSChuanqi Xuresults of the compilations. We expect that there are many more opportunities
7136f710fefSChuanqi Xufor this optimization than we currently have realized and would appreaciate
7146f710fefSChuanqi Xufeedback about missed optimization opportunities. For example,
7156f710fefSChuanqi Xu
7166f710fefSChuanqi Xu.. code-block:: c++
7176f710fefSChuanqi Xu
7186f710fefSChuanqi Xu  // m-partA.cppm
7196f710fefSChuanqi Xu  export module m:partA;
7206f710fefSChuanqi Xu
7216f710fefSChuanqi Xu  // m-partB.cppm
7226f710fefSChuanqi Xu  export module m:partB;
7236f710fefSChuanqi Xu  export int getB() { return 44; }
7246f710fefSChuanqi Xu
7256f710fefSChuanqi Xu  // m.cppm
7266f710fefSChuanqi Xu  export module m;
7276f710fefSChuanqi Xu  export import :partA;
7286f710fefSChuanqi Xu  export import :partB;
7296f710fefSChuanqi Xu
7306f710fefSChuanqi Xu  // useBOnly.cppm
7316f710fefSChuanqi Xu  export module useBOnly;
7326f710fefSChuanqi Xu  import m;
7336f710fefSChuanqi Xu  export int B() {
7346f710fefSChuanqi Xu    return getB();
7356f710fefSChuanqi Xu  }
7366f710fefSChuanqi Xu
7376f710fefSChuanqi Xu  // Use.cc
7386f710fefSChuanqi Xu  import useBOnly;
7396f710fefSChuanqi Xu  int get() {
7406f710fefSChuanqi Xu    return B();
7416f710fefSChuanqi Xu  }
7426f710fefSChuanqi Xu
7436f710fefSChuanqi XuTo compile the project (for brevity, some commands are omitted.):
7446f710fefSChuanqi Xu
7456f710fefSChuanqi Xu.. code-block:: console
7466f710fefSChuanqi Xu
7476f710fefSChuanqi Xu  $ clang++ -std=c++20 m-partA.cppm --precompile -o m-partA.pcm
7486f710fefSChuanqi Xu  $ clang++ -std=c++20 m-partB.cppm --precompile -o m-partB.pcm
7496f710fefSChuanqi Xu  $ clang++ -std=c++20 m.cppm --precompile -o m.pcm -fprebuilt-module-path=.
7506f710fefSChuanqi Xu  $ clang++ -std=c++20 useBOnly.cppm --precompile -o useBOnly.pcm -fprebuilt-module-path=.
7516f710fefSChuanqi Xu  $ md5sum useBOnly.pcm
7526f710fefSChuanqi Xu  07656bf4a6908626795729295f9608da  useBOnly.pcm
7536f710fefSChuanqi Xu
7546f710fefSChuanqi XuIf the interface of ``m-partA.cppm`` is changed to:
7556f710fefSChuanqi Xu
7566f710fefSChuanqi Xu.. code-block:: c++
7576f710fefSChuanqi Xu
7586f710fefSChuanqi Xu  // m-partA.v1.cppm
7596f710fefSChuanqi Xu  export module m:partA;
7606f710fefSChuanqi Xu  export int getA() { return 43; }
7616f710fefSChuanqi Xu
7626f710fefSChuanqi Xuand the BMI for ``useBOnly`` is recompiled as in:
7636f710fefSChuanqi Xu
7646f710fefSChuanqi Xu.. code-block:: console
7656f710fefSChuanqi Xu
7666f710fefSChuanqi Xu  $ clang++ -std=c++20 m-partA.cppm --precompile -o m-partA.pcm
7676f710fefSChuanqi Xu  $ clang++ -std=c++20 m-partB.cppm --precompile -o m-partB.pcm
7686f710fefSChuanqi Xu  $ clang++ -std=c++20 m.cppm --precompile -o m.pcm -fprebuilt-module-path=.
7696f710fefSChuanqi Xu  $ clang++ -std=c++20 useBOnly.cppm --precompile -o useBOnly.pcm -fprebuilt-module-path=.
7706f710fefSChuanqi Xu  $ md5sum useBOnly.pcm
7716f710fefSChuanqi Xu  07656bf4a6908626795729295f9608da  useBOnly.pcm
7726f710fefSChuanqi Xu
7736f710fefSChuanqi Xuthen the contents of ``useBOnly.pcm`` remain unchanged.
7746f710fefSChuanqi XuConsequently, if the build system only bases recompilation decisions on directly imported modules,
7756f710fefSChuanqi Xuit becomes possible to skip the recompilation of ``Use.cc``.
7766f710fefSChuanqi XuIt should be fine because the altered interfaces do not affect ``Use.cc`` in any way;
7776f710fefSChuanqi Xuthe changes do not cascade.
7786f710fefSChuanqi Xu
7796f710fefSChuanqi XuWhen ``Clang`` generates a BMI, it records the hash values of all potentially contributory BMIs
7806f710fefSChuanqi Xufor the BMI being produced. This ensures that build systems are not required to consider
7816f710fefSChuanqi Xutransitively imported modules when deciding whether to recompile.
7826f710fefSChuanqi Xu
7836f710fefSChuanqi XuWhat is considered to be a potential contributory BMIs is currently unspecified.
7846f710fefSChuanqi XuHowever, it is a severe bug for a BMI to remain unchanged following an observable change
7856f710fefSChuanqi Xuthat affects its consumers.
7866f710fefSChuanqi Xu
7876f710fefSChuanqi XuBuild systems may utilize this optimization by doing an update-if-changed operation to the BMI
7886f710fefSChuanqi Xuthat is consumed from the BMI that is output by the compiler.
7896f710fefSChuanqi Xu
7906f710fefSChuanqi XuWe encourage build systems to add an experimental mode that
7916f710fefSChuanqi Xureuses the cached BMI when **direct** dependencies did not change,
7926f710fefSChuanqi Xueven if **transitive** dependencies did change.
7936f710fefSChuanqi Xu
7946f710fefSChuanqi XuGiven there are potential compiler bugs, we recommend that build systems
7956f710fefSChuanqi Xusupport this feature as a configurable option so that users
7966f710fefSChuanqi Xucan go back to the transitive change mode safely at any time.
7976f710fefSChuanqi Xu
7986f710fefSChuanqi XuInteractions with Reduced BMI
7996f710fefSChuanqi Xu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8006f710fefSChuanqi Xu
8016f710fefSChuanqi XuWith reduced BMI, non-cascading changes can be more powerful. For example,
8026f710fefSChuanqi Xu
8036f710fefSChuanqi Xu.. code-block:: c++
8046f710fefSChuanqi Xu
8056f710fefSChuanqi Xu  // A.cppm
8066f710fefSChuanqi Xu  export module A;
8076f710fefSChuanqi Xu  export int a() { return 44; }
8086f710fefSChuanqi Xu
8096f710fefSChuanqi Xu  // B.cppm
8106f710fefSChuanqi Xu  export module B;
8116f710fefSChuanqi Xu  import A;
8126f710fefSChuanqi Xu  export int b() { return a(); }
8136f710fefSChuanqi Xu
8146f710fefSChuanqi Xu.. code-block:: console
8156f710fefSChuanqi Xu
816*411196b9SChuanqi Xu  $ clang++ -std=c++20 A.cppm -c -fmodule-output=A.pcm  -fmodules-reduced-bmi -o A.o
817*411196b9SChuanqi Xu  $ clang++ -std=c++20 B.cppm -c -fmodule-output=B.pcm  -fmodules-reduced-bmi -o B.o -fmodule-file=A=A.pcm
8186f710fefSChuanqi Xu  $ md5sum B.pcm
8196f710fefSChuanqi Xu  6c2bd452ca32ab418bf35cd141b060b9  B.pcm
8206f710fefSChuanqi Xu
8216f710fefSChuanqi XuAnd let's change the implementation for ``A.cppm`` into:
8226f710fefSChuanqi Xu
8236f710fefSChuanqi Xu.. code-block:: c++
8246f710fefSChuanqi Xu
8256f710fefSChuanqi Xu  export module A;
8266f710fefSChuanqi Xu  int a_impl() { return 99; }
8276f710fefSChuanqi Xu  export int a() { return a_impl(); }
8286f710fefSChuanqi Xu
8296f710fefSChuanqi Xuand recompile the example:
8306f710fefSChuanqi Xu
8316f710fefSChuanqi Xu.. code-block:: console
8326f710fefSChuanqi Xu
833*411196b9SChuanqi Xu  $ clang++ -std=c++20 A.cppm -c -fmodule-output=A.pcm  -fmodules-reduced-bmi -o A.o
834*411196b9SChuanqi Xu  $ clang++ -std=c++20 B.cppm -c -fmodule-output=B.pcm  -fmodules-reduced-bmi -o B.o -fmodule-file=A=A.pcm
8356f710fefSChuanqi Xu  $ md5sum B.pcm
8366f710fefSChuanqi Xu  6c2bd452ca32ab418bf35cd141b060b9  B.pcm
8376f710fefSChuanqi Xu
8386f710fefSChuanqi XuWe should find the contents of ``B.pcm`` remains the same. In this case, the build system is
8396f710fefSChuanqi Xuallowed to skip recompilations of TUs which solely and directly depend on module ``B``.
8406f710fefSChuanqi Xu
8416f710fefSChuanqi XuThis only happens with a reduced BMI. With reduced BMIs, we won't record the function body
8426f710fefSChuanqi Xuof ``int b()`` in the BMI for ``B`` so that the module ``A`` doesn't contribute to the BMI of ``B``
8436f710fefSChuanqi Xuand we have less dependencies.
8446f710fefSChuanqi Xu
8450d6ea6fcSChuanqi XuPerformance Tips
8460d6ea6fcSChuanqi Xu----------------
8470d6ea6fcSChuanqi Xu
8480d6ea6fcSChuanqi XuReduce duplications
8490d6ea6fcSChuanqi Xu~~~~~~~~~~~~~~~~~~~
8500d6ea6fcSChuanqi Xu
8519263318fSAaron BallmanWhile it is valid to have duplicated declarations in the global module fragments
8529263318fSAaron Ballmanof different module units, it is not free for Clang to deal with the duplicated
8539263318fSAaron Ballmandeclarations. A translation unit will compile more slowly if there is a lot of
8549263318fSAaron Ballmanduplicated declarations between the translation unit and modules it imports.
8559263318fSAaron BallmanFor example:
8560d6ea6fcSChuanqi Xu
8570d6ea6fcSChuanqi Xu.. code-block:: c++
8580d6ea6fcSChuanqi Xu
8590d6ea6fcSChuanqi Xu  // M-partA.cppm
8600d6ea6fcSChuanqi Xu  module;
8610d6ea6fcSChuanqi Xu  #include "big.header.h"
8620d6ea6fcSChuanqi Xu  export module M:partA;
8630d6ea6fcSChuanqi Xu  ...
8640d6ea6fcSChuanqi Xu
8650d6ea6fcSChuanqi Xu  // M-partB.cppm
8660d6ea6fcSChuanqi Xu  module;
8670d6ea6fcSChuanqi Xu  #include "big.header.h"
8680d6ea6fcSChuanqi Xu  export module M:partB;
8690d6ea6fcSChuanqi Xu  ...
8700d6ea6fcSChuanqi Xu
8710d6ea6fcSChuanqi Xu  // other partitions
8720d6ea6fcSChuanqi Xu  ...
8730d6ea6fcSChuanqi Xu
8740d6ea6fcSChuanqi Xu  // M-partZ.cppm
8750d6ea6fcSChuanqi Xu  module;
8760d6ea6fcSChuanqi Xu  #include "big.header.h"
8770d6ea6fcSChuanqi Xu  export module M:partZ;
8780d6ea6fcSChuanqi Xu  ...
8790d6ea6fcSChuanqi Xu
8800d6ea6fcSChuanqi Xu  // M.cppm
8810d6ea6fcSChuanqi Xu  export module M;
8820d6ea6fcSChuanqi Xu  export import :partA;
8830d6ea6fcSChuanqi Xu  export import :partB;
8840d6ea6fcSChuanqi Xu  ...
8850d6ea6fcSChuanqi Xu  export import :partZ;
8860d6ea6fcSChuanqi Xu
8870d6ea6fcSChuanqi Xu  // use.cpp
8880d6ea6fcSChuanqi Xu  import M;
8890d6ea6fcSChuanqi Xu  ... // use declarations from module M.
8900d6ea6fcSChuanqi Xu
8919263318fSAaron BallmanWhen ``big.header.h`` is big enough and there are a lot of partitions, the
8929263318fSAaron Ballmancompilation of ``use.cpp`` may be significantly slower than the following
8939263318fSAaron Ballmanapproach:
8940d6ea6fcSChuanqi Xu
8950d6ea6fcSChuanqi Xu.. code-block:: c++
8965e601ad3SChuanqi Xu
8970d6ea6fcSChuanqi Xu  module;
8980d6ea6fcSChuanqi Xu  #include "big.header.h"
8990d6ea6fcSChuanqi Xu  export module m:big.header.wrapper;
9000d6ea6fcSChuanqi Xu  export ... // export the needed declarations
9010d6ea6fcSChuanqi Xu
9020d6ea6fcSChuanqi Xu  // M-partA.cppm
9030d6ea6fcSChuanqi Xu  export module M:partA;
9040d6ea6fcSChuanqi Xu  import :big.header.wrapper;
9050d6ea6fcSChuanqi Xu  ...
9060d6ea6fcSChuanqi Xu
9070d6ea6fcSChuanqi Xu  // M-partB.cppm
9080d6ea6fcSChuanqi Xu  export module M:partB;
9090d6ea6fcSChuanqi Xu  import :big.header.wrapper;
9100d6ea6fcSChuanqi Xu  ...
9110d6ea6fcSChuanqi Xu
9120d6ea6fcSChuanqi Xu  // other partitions
9130d6ea6fcSChuanqi Xu  ...
9140d6ea6fcSChuanqi Xu
9150d6ea6fcSChuanqi Xu  // M-partZ.cppm
9160d6ea6fcSChuanqi Xu  export module M:partZ;
9170d6ea6fcSChuanqi Xu  import :big.header.wrapper;
9180d6ea6fcSChuanqi Xu  ...
9190d6ea6fcSChuanqi Xu
9200d6ea6fcSChuanqi Xu  // M.cppm
9210d6ea6fcSChuanqi Xu  export module M;
9220d6ea6fcSChuanqi Xu  export import :partA;
9230d6ea6fcSChuanqi Xu  export import :partB;
9240d6ea6fcSChuanqi Xu  ...
9250d6ea6fcSChuanqi Xu  export import :partZ;
9260d6ea6fcSChuanqi Xu
9270d6ea6fcSChuanqi Xu  // use.cpp
9280d6ea6fcSChuanqi Xu  import M;
9290d6ea6fcSChuanqi Xu  ... // use declarations from module M.
9300d6ea6fcSChuanqi Xu
9319263318fSAaron BallmanReducing the duplication from textual includes is what improves compile-time
9329263318fSAaron Ballmanperformance.
9330d6ea6fcSChuanqi Xu
93488f9ac38SChuanqi XuTo help users to identify such issues, we add a warning ``-Wdecls-in-multiple-modules``.
93588f9ac38SChuanqi XuThis warning is disabled by default and it needs to be explicitly enabled or by ``-Weverything``.
93688f9ac38SChuanqi Xu
9379263318fSAaron BallmanTransitioning to modules
9389263318fSAaron Ballman------------------------
939c8fab880SChuanqi Xu
9409263318fSAaron BallmanIt is best for new code and libraries to use modules from the start if
9419263318fSAaron Ballmanpossible. However, it may be a breaking change for existing code or libraries
9429263318fSAaron Ballmanto switch to modules. As a result, many existing libraries need to provide
9439263318fSAaron Ballmanboth headers and module interfaces for a while to not break existing users.
944c8fab880SChuanqi Xu
9459263318fSAaron BallmanThis section suggests some suggestions on how to ease the transition process
9469263318fSAaron Ballmanfor existing libraries. **Note that this information is only intended as
9479263318fSAaron Ballmanguidance, rather than as requirements to use modules in Clang.** It presumes
9489263318fSAaron Ballmanthe project is starting with no module-based dependencies.
949c8fab880SChuanqi Xu
950c8fab880SChuanqi XuABI non-breaking styles
951c8fab880SChuanqi Xu~~~~~~~~~~~~~~~~~~~~~~~
952c8fab880SChuanqi Xu
953c8fab880SChuanqi Xuexport-using style
954c8fab880SChuanqi Xu^^^^^^^^^^^^^^^^^^
955c8fab880SChuanqi Xu
956c8fab880SChuanqi Xu.. code-block:: c++
957c8fab880SChuanqi Xu
958c8fab880SChuanqi Xu  module;
959c8fab880SChuanqi Xu  #include "header_1.h"
960c8fab880SChuanqi Xu  #include "header_2.h"
961c8fab880SChuanqi Xu  ...
962c8fab880SChuanqi Xu  #include "header_n.h"
963c8fab880SChuanqi Xu  export module your_library;
964c8fab880SChuanqi Xu  export namespace your_namespace {
965c8fab880SChuanqi Xu    using decl_1;
966c8fab880SChuanqi Xu    using decl_2;
967c8fab880SChuanqi Xu    ...
968c8fab880SChuanqi Xu    using decl_n;
969c8fab880SChuanqi Xu  }
970c8fab880SChuanqi Xu
9719263318fSAaron BallmanThis example shows how to include all the headers containing declarations which
9729263318fSAaron Ballmanneed to be exported, and uses `using` declarations in an `export` block to
9739263318fSAaron Ballmanproduce the module interface.
974c8fab880SChuanqi Xu
975c8fab880SChuanqi Xuexport extern-C++ style
976c8fab880SChuanqi Xu^^^^^^^^^^^^^^^^^^^^^^^
977c8fab880SChuanqi Xu
978c8fab880SChuanqi Xu.. code-block:: c++
979c8fab880SChuanqi Xu
980c8fab880SChuanqi Xu  module;
981c8fab880SChuanqi Xu  #include "third_party/A/headers.h"
982c8fab880SChuanqi Xu  #include "third_party/B/headers.h"
983c8fab880SChuanqi Xu  ...
984c8fab880SChuanqi Xu  #include "third_party/Z/headers.h"
985c8fab880SChuanqi Xu  export module your_library;
986c8fab880SChuanqi Xu  #define IN_MODULE_INTERFACE
987c8fab880SChuanqi Xu  extern "C++" {
988c8fab880SChuanqi Xu    #include "header_1.h"
989c8fab880SChuanqi Xu    #include "header_2.h"
990c8fab880SChuanqi Xu    ...
991c8fab880SChuanqi Xu    #include "header_n.h"
992c8fab880SChuanqi Xu  }
993c8fab880SChuanqi Xu
9949263318fSAaron BallmanHeaders (from ``header_1.h`` to ``header_n.h``) need to define the macro:
995c8fab880SChuanqi Xu
996c8fab880SChuanqi Xu.. code-block:: c++
997c8fab880SChuanqi Xu
998c8fab880SChuanqi Xu  #ifdef IN_MODULE_INTERFACE
999c8fab880SChuanqi Xu  #define EXPORT export
1000c8fab880SChuanqi Xu  #else
1001c8fab880SChuanqi Xu  #define EXPORT
1002c8fab880SChuanqi Xu  #endif
1003c8fab880SChuanqi Xu
10049263318fSAaron Ballmanand put ``EXPORT`` on the declarations you want to export.
1005c8fab880SChuanqi Xu
10069263318fSAaron BallmanAlso, it is recommended to refactor headers to include third-party headers
10079263318fSAaron Ballmanconditionally:
1008c8fab880SChuanqi Xu
1009c8fab880SChuanqi Xu.. code-block:: c++
1010c8fab880SChuanqi Xu
1011c8fab880SChuanqi Xu  #ifndef IN_MODULE_INTERFACE
1012c8fab880SChuanqi Xu  #include "third_party/A/headers.h"
1013c8fab880SChuanqi Xu  #endif
1014c8fab880SChuanqi Xu
1015c8fab880SChuanqi Xu  #include "header_x.h"
1016c8fab880SChuanqi Xu
1017c8fab880SChuanqi Xu  ...
1018c8fab880SChuanqi Xu
10199263318fSAaron BallmanThis can be helpful because it gives better diagnostic messages if the module
10209263318fSAaron Ballmaninterface unit is not properly updated when modifying code.
1021c8fab880SChuanqi Xu
10229263318fSAaron BallmanThis approach works because the declarations with language linkage are attached
10239263318fSAaron Ballmanto the global module. Thus, the ABI of the modular form of the library does not
10249263318fSAaron Ballmanchange.
1025c8fab880SChuanqi Xu
10269263318fSAaron BallmanWhile this style is more involved than the export-using style, it makes it
10279263318fSAaron Ballmaneasier to further refactor the library to other styles.
1028c8fab880SChuanqi Xu
1029c8fab880SChuanqi XuABI breaking style
1030c8fab880SChuanqi Xu~~~~~~~~~~~~~~~~~~
1031c8fab880SChuanqi Xu
10329263318fSAaron BallmanThe term ``ABI breaking`` may sound like a bad approach. However, this style
10339263318fSAaron Ballmanforces consumers of the library use it in a consistent way. e.g., either always
10349263318fSAaron Ballmaninclude headers for the library or always import modules. The style prevents
10359263318fSAaron Ballmanthe ability to mix includes and imports for the library.
1036c8fab880SChuanqi Xu
10379263318fSAaron BallmanThe pattern for ABI breaking style is similar to the export extern-C++ style.
1038c8fab880SChuanqi Xu
1039c8fab880SChuanqi Xu.. code-block:: c++
1040c8fab880SChuanqi Xu
1041c8fab880SChuanqi Xu  module;
1042c8fab880SChuanqi Xu  #include "third_party/A/headers.h"
1043c8fab880SChuanqi Xu  #include "third_party/B/headers.h"
1044c8fab880SChuanqi Xu  ...
1045c8fab880SChuanqi Xu  #include "third_party/Z/headers.h"
1046c8fab880SChuanqi Xu  export module your_library;
1047c8fab880SChuanqi Xu  #define IN_MODULE_INTERFACE
1048c8fab880SChuanqi Xu  #include "header_1.h"
1049c8fab880SChuanqi Xu  #include "header_2.h"
1050c8fab880SChuanqi Xu  ...
1051c8fab880SChuanqi Xu  #include "header_n.h"
1052c8fab880SChuanqi Xu
1053c8fab880SChuanqi Xu  #if the number of .cpp files in your project are small
1054c8fab880SChuanqi Xu  module :private;
1055c8fab880SChuanqi Xu  #include "source_1.cpp"
1056c8fab880SChuanqi Xu  #include "source_2.cpp"
1057c8fab880SChuanqi Xu  ...
1058c8fab880SChuanqi Xu  #include "source_n.cpp"
1059c8fab880SChuanqi Xu  #else // the number of .cpp files in your project are a lot
10609263318fSAaron Ballman  // Using all the declarations from third-party libraries which are
1061c8fab880SChuanqi Xu  // used in the .cpp files.
1062c8fab880SChuanqi Xu  namespace third_party_namespace {
1063c8fab880SChuanqi Xu    using third_party_decl_used_in_cpp_1;
1064c8fab880SChuanqi Xu    using third_party_decl_used_in_cpp_2;
1065c8fab880SChuanqi Xu    ...
1066c8fab880SChuanqi Xu    using third_party_decl_used_in_cpp_n;
1067c8fab880SChuanqi Xu  }
1068c8fab880SChuanqi Xu  #endif
1069c8fab880SChuanqi Xu
10709263318fSAaron Ballman(And add `EXPORT` and conditional include to the headers as suggested in the
10719263318fSAaron Ballmanexport extern-C++ style section.)
1072c8fab880SChuanqi Xu
10739263318fSAaron BallmanThe ABI with modules is different and thus we need to compile the source files
10749263318fSAaron Ballmaninto the new ABI. This is done by an additional part of the interface unit:
1075c8fab880SChuanqi Xu
1076c8fab880SChuanqi Xu.. code-block:: c++
1077c8fab880SChuanqi Xu
1078c8fab880SChuanqi Xu  #if the number of .cpp files in your project are small
1079c8fab880SChuanqi Xu  module :private;
1080c8fab880SChuanqi Xu  #include "source_1.cpp"
1081c8fab880SChuanqi Xu  #include "source_2.cpp"
1082c8fab880SChuanqi Xu  ...
1083c8fab880SChuanqi Xu  #include "source_n.cpp"
1084c8fab880SChuanqi Xu  #else // the number of .cpp files in your project are a lot
10859263318fSAaron Ballman  // Using all the declarations from third-party libraries which are
1086c8fab880SChuanqi Xu  // used in the .cpp files.
1087c8fab880SChuanqi Xu  namespace third_party_namespace {
1088c8fab880SChuanqi Xu    using third_party_decl_used_in_cpp_1;
1089c8fab880SChuanqi Xu    using third_party_decl_used_in_cpp_2;
1090c8fab880SChuanqi Xu    ...
1091c8fab880SChuanqi Xu    using third_party_decl_used_in_cpp_n;
1092c8fab880SChuanqi Xu  }
1093c8fab880SChuanqi Xu  #endif
1094c8fab880SChuanqi Xu
10959263318fSAaron BallmanIf the number of source files is small, everything can be put in the private
10969263318fSAaron Ballmanmodule fragment directly (it is recommended to add conditional includes to the
10979263318fSAaron Ballmansource files as well). However, compile time performance will be bad if there
10989263318fSAaron Ballmanare a lot of source files to compile.
1099c8fab880SChuanqi Xu
11009263318fSAaron Ballman**Note that the private module fragment can only be in the primary module
11019263318fSAaron Ballmaninterface unit and the primary module interface unit containing the private
11029263318fSAaron Ballmanmodule fragment should be the only module unit of the corresponding module.**
1103c8fab880SChuanqi Xu
11049263318fSAaron BallmanIn this case, source files (.cpp files) must be converted to module
11059263318fSAaron Ballmanimplementation units:
1106c8fab880SChuanqi Xu
1107c8fab880SChuanqi Xu.. code-block:: c++
1108c8fab880SChuanqi Xu
1109c8fab880SChuanqi Xu  #ifndef IN_MODULE_INTERFACE
1110c8fab880SChuanqi Xu  // List all the includes here.
1111c8fab880SChuanqi Xu  #include "third_party/A/headers.h"
1112c8fab880SChuanqi Xu  ...
1113c8fab880SChuanqi Xu  #include "header.h"
1114c8fab880SChuanqi Xu  #endif
1115c8fab880SChuanqi Xu
1116c8fab880SChuanqi Xu  module your_library;
1117c8fab880SChuanqi Xu
1118c8fab880SChuanqi Xu  // Following off should be unchanged.
1119c8fab880SChuanqi Xu  ...
1120c8fab880SChuanqi Xu
11219263318fSAaron BallmanThe module implementation unit will import the primary module implicitly. Do
11229263318fSAaron Ballmannot include any headers in the module implementation units as it avoids
11239263318fSAaron Ballmanduplicated declarations between translation units. This is why non-exported
11249263318fSAaron Ballmanusing declarations should be added from third-party libraries in the primary
11259263318fSAaron Ballmanmodule interface unit.
1126c8fab880SChuanqi Xu
11279263318fSAaron BallmanIf the library is provided as ``libyour_library.so``, a modular library (e.g.,
11289263318fSAaron Ballman``libyour_library_modules.so``) may also need to be provided for ABI
11299263318fSAaron Ballmancompatibility.
1130c8fab880SChuanqi Xu
11319263318fSAaron BallmanWhat if there are headers only included by the source files
11329263318fSAaron Ballman^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1133c8fab880SChuanqi Xu
11349263318fSAaron BallmanThe above practice may be problematic if there are headers only included by the
11359263318fSAaron Ballmansource files. When using a private module fragment, this issue may be solved by
11369263318fSAaron Ballmanincluding those headers in the private module fragment. While it is OK to solve
11379263318fSAaron Ballmanit by including the implementation headers in the module purview when using
11389263318fSAaron Ballmanimplementation module units, it may be suboptimal because the primary module
11399263318fSAaron Ballmaninterface units now contain entities that do not belong to the interface.
1140c8fab880SChuanqi Xu
11419263318fSAaron BallmanThis can potentially be improved by introducing a module partition
11429263318fSAaron Ballmanimplementation unit. An internal module partition unit is an importable
11439263318fSAaron Ballmanmodule unit which is internal to the module itself.
1144c8fab880SChuanqi Xu
1145c8fab880SChuanqi XuProviding a header to skip parsing redundant headers
1146c8fab880SChuanqi Xu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1147c8fab880SChuanqi Xu
11489263318fSAaron BallmanMany redeclarations shared between translation units causes Clang to have
11499263318fSAaron Ballmanslower compile-time performance. Further, there are known issues with
11509263318fSAaron Ballman`include after import <https://github.com/llvm/llvm-project/issues/61465>`_.
11519263318fSAaron BallmanEven when that issue is resolved, users may still get slower compilation speed
11529263318fSAaron Ballmanand larger BMIs. For these reasons, it is recommended to not include headers
11539263318fSAaron Ballmanafter importing the corresponding module. However, it is not always easy if the
11549263318fSAaron Ballmanlibrary is included by other dependencies, as in:
1155c8fab880SChuanqi Xu
1156c8fab880SChuanqi Xu.. code-block:: c++
1157c8fab880SChuanqi Xu
1158c8fab880SChuanqi Xu  #include "third_party/A.h" // #include "your_library/a_header.h"
1159c8fab880SChuanqi Xu  import your_library;
1160c8fab880SChuanqi Xu
1161c8fab880SChuanqi Xuor
1162c8fab880SChuanqi Xu
1163c8fab880SChuanqi Xu.. code-block:: c++
1164c8fab880SChuanqi Xu
1165c8fab880SChuanqi Xu  import your_library;
1166c8fab880SChuanqi Xu  #include "third_party/A.h" // #include "your_library/a_header.h"
1167c8fab880SChuanqi Xu
11689263318fSAaron BallmanFor such cases, it is best if the library providing both module and header
11699263318fSAaron Ballmaninterfaces also provides a header which skips parsing so that the library can
11709263318fSAaron Ballmanbe imported with the following approach that skips redundant redeclarations:
1171c8fab880SChuanqi Xu
1172c8fab880SChuanqi Xu.. code-block:: c++
1173c8fab880SChuanqi Xu
1174c8fab880SChuanqi Xu  import your_library;
1175c8fab880SChuanqi Xu  #include "your_library_imported.h"
1176c8fab880SChuanqi Xu  #include "third_party/A.h" // #include "your_library/a_header.h" but got skipped
1177c8fab880SChuanqi Xu
11789263318fSAaron BallmanThe implementation of ``your_library_imported.h`` can be a set of controlling
11799263318fSAaron Ballmanmacros or an overall controlling macro if using `#pragma once`. Then headers
11809263318fSAaron Ballmancan be refactored to:
1181c8fab880SChuanqi Xu
1182c8fab880SChuanqi Xu.. code-block:: c++
1183c8fab880SChuanqi Xu
1184c8fab880SChuanqi Xu  #pragma once
1185c8fab880SChuanqi Xu  #ifndef YOUR_LIBRARY_IMPORTED
1186c8fab880SChuanqi Xu  ...
1187c8fab880SChuanqi Xu  #endif
1188c8fab880SChuanqi Xu
11899263318fSAaron BallmanIf the modules imported by the library provide such headers, remember to add
11909263318fSAaron Ballmanthem to ``your_library_imported.h`` too.
1191b014944eSChuanqi Xu
1192c8fab880SChuanqi XuImporting modules
1193c8fab880SChuanqi Xu~~~~~~~~~~~~~~~~~
1194c8fab880SChuanqi Xu
11959263318fSAaron BallmanWhen there are dependent libraries providing modules, they should be imported
11969263318fSAaron Ballmanin your module as well. Many existing libraries will fall into this category
11979263318fSAaron Ballmanonce the ``std`` module is more widely available.
1198c8fab880SChuanqi Xu
1199c8fab880SChuanqi XuAll dependent libraries providing modules
1200c8fab880SChuanqi Xu^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1201c8fab880SChuanqi Xu
12029263318fSAaron BallmanOf course, most of the complexity disappears if all the dependent libraries
12039263318fSAaron Ballmanprovide modules.
1204c8fab880SChuanqi Xu
12059263318fSAaron BallmanHeaders need to be converted to include third-party headers conditionally. Then,
12069263318fSAaron Ballmanfor the export-using style:
1207c8fab880SChuanqi Xu
1208c8fab880SChuanqi Xu.. code-block:: c++
1209c8fab880SChuanqi Xu
1210c8fab880SChuanqi Xu  module;
1211c8fab880SChuanqi Xu  import modules_from_third_party;
1212c8fab880SChuanqi Xu  #define IN_MODULE_INTERFACE
1213c8fab880SChuanqi Xu  #include "header_1.h"
1214c8fab880SChuanqi Xu  #include "header_2.h"
1215c8fab880SChuanqi Xu  ...
1216c8fab880SChuanqi Xu  #include "header_n.h"
1217c8fab880SChuanqi Xu  export module your_library;
1218c8fab880SChuanqi Xu  export namespace your_namespace {
1219c8fab880SChuanqi Xu    using decl_1;
1220c8fab880SChuanqi Xu    using decl_2;
1221c8fab880SChuanqi Xu    ...
1222c8fab880SChuanqi Xu    using decl_n;
1223c8fab880SChuanqi Xu  }
1224c8fab880SChuanqi Xu
12259263318fSAaron Ballmanor, for the export extern-C++ style:
1226c8fab880SChuanqi Xu
1227c8fab880SChuanqi Xu.. code-block:: c++
1228c8fab880SChuanqi Xu
1229c8fab880SChuanqi Xu  export module your_library;
1230c8fab880SChuanqi Xu  import modules_from_third_party;
1231c8fab880SChuanqi Xu  #define IN_MODULE_INTERFACE
1232c8fab880SChuanqi Xu  extern "C++" {
1233c8fab880SChuanqi Xu    #include "header_1.h"
1234c8fab880SChuanqi Xu    #include "header_2.h"
1235c8fab880SChuanqi Xu    ...
1236c8fab880SChuanqi Xu    #include "header_n.h"
1237c8fab880SChuanqi Xu  }
1238c8fab880SChuanqi Xu
12399263318fSAaron Ballmanor, for the ABI-breaking style,
1240c8fab880SChuanqi Xu
1241c8fab880SChuanqi Xu.. code-block:: c++
1242c8fab880SChuanqi Xu
1243c8fab880SChuanqi Xu  export module your_library;
1244c8fab880SChuanqi Xu  import modules_from_third_party;
1245c8fab880SChuanqi Xu  #define IN_MODULE_INTERFACE
1246c8fab880SChuanqi Xu  #include "header_1.h"
1247c8fab880SChuanqi Xu  #include "header_2.h"
1248c8fab880SChuanqi Xu  ...
1249c8fab880SChuanqi Xu  #include "header_n.h"
1250c8fab880SChuanqi Xu
1251c8fab880SChuanqi Xu  #if the number of .cpp files in your project are small
1252c8fab880SChuanqi Xu  module :private;
1253c8fab880SChuanqi Xu  #include "source_1.cpp"
1254c8fab880SChuanqi Xu  #include "source_2.cpp"
1255c8fab880SChuanqi Xu  ...
1256c8fab880SChuanqi Xu  #include "source_n.cpp"
1257c8fab880SChuanqi Xu  #endif
1258c8fab880SChuanqi Xu
12599263318fSAaron BallmanNon-exported ``using`` declarations are unnecessary if using implementation
12609263318fSAaron Ballmanmodule units. Instead, third-party modules can be imported directly in
12619263318fSAaron Ballmanimplementation module units.
1262c8fab880SChuanqi Xu
1263c8fab880SChuanqi XuPartial dependent libraries providing modules
1264c8fab880SChuanqi Xu^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1265c8fab880SChuanqi Xu
12669263318fSAaron BallmanIf the library has to mix the use of ``include`` and ``import`` in its module,
12679263318fSAaron Ballmanthe primary goal is still the removal of duplicated declarations in translation
12689263318fSAaron Ballmanunits as much as possible. If the imported modules provide headers to skip
12699263318fSAaron Ballmanparsing their headers, those should be included after the import. If the
12709263318fSAaron Ballmanimported modules don't provide such a header, one can be made manually for
12719263318fSAaron Ballmanimproved compile time performance.
1272c8fab880SChuanqi Xu
127385b113c3SChuanqi XuReachability of internal partition units
127485b113c3SChuanqi Xu----------------------------------------
127585b113c3SChuanqi Xu
127685b113c3SChuanqi XuThe internal partition units are sometimes called implementation partition units in other documentation.
127785b113c3SChuanqi XuHowever, the name may be confusing since implementation partition units are not implementation
127885b113c3SChuanqi Xuunits.
127985b113c3SChuanqi Xu
128085b113c3SChuanqi XuAccording to `[module.reach]p1 <https://eel.is/c++draft/module.reach#1>`_ and
128185b113c3SChuanqi Xu`[module.reach]p2 <https://eel.is/c++draft/module.reach#2>`_ (from N4986):
128285b113c3SChuanqi Xu
128385b113c3SChuanqi Xu  A translation unit U is necessarily reachable from a point P if U is a module
128485b113c3SChuanqi Xu  interface unit on which the translation unit containing P has an interface
128585b113c3SChuanqi Xu  dependency, or the translation unit containing P imports U, in either case
128685b113c3SChuanqi Xu  prior to P.
128785b113c3SChuanqi Xu
128885b113c3SChuanqi Xu  All translation units that are necessarily reachable are reachable. Additional
128985b113c3SChuanqi Xu  translation units on which the point within the program has an interface
129085b113c3SChuanqi Xu  dependency may be considered reachable, but it is unspecified which are and
129185b113c3SChuanqi Xu  under what circumstances.
129285b113c3SChuanqi Xu
129385b113c3SChuanqi XuFor example,
129485b113c3SChuanqi Xu
129585b113c3SChuanqi Xu.. code-block:: c++
129685b113c3SChuanqi Xu
129785b113c3SChuanqi Xu  // a.cpp
129885b113c3SChuanqi Xu  import B;
129985b113c3SChuanqi Xu  int main()
130085b113c3SChuanqi Xu  {
130185b113c3SChuanqi Xu      g<void>();
130285b113c3SChuanqi Xu  }
130385b113c3SChuanqi Xu
130485b113c3SChuanqi Xu  // b.cppm
130585b113c3SChuanqi Xu  export module B;
130685b113c3SChuanqi Xu  import :C;
130785b113c3SChuanqi Xu  export template <typename T> inline void g() noexcept
130885b113c3SChuanqi Xu  {
130985b113c3SChuanqi Xu      return f<T>();
131085b113c3SChuanqi Xu  }
131185b113c3SChuanqi Xu
131285b113c3SChuanqi Xu  // c.cppm
131385b113c3SChuanqi Xu  module B:C;
131485b113c3SChuanqi Xu  template<typename> inline void f() noexcept {}
131585b113c3SChuanqi Xu
131685b113c3SChuanqi XuThe internal partition unit ``c.cppm`` is not necessarily reachable by
131785b113c3SChuanqi Xu``a.cpp`` because ``c.cppm`` is not a module interface unit and ``a.cpp``
131885b113c3SChuanqi Xudoesn't import ``c.cppm``. This leaves it up to the compiler to decide if
131985b113c3SChuanqi Xu``c.cppm`` is reachable by ``a.cpp`` or not. Clang's behavior is that
132085b113c3SChuanqi Xuindirectly imported internal partition units are not reachable.
132185b113c3SChuanqi Xu
132285b113c3SChuanqi XuThe suggested approach for using an internal partition unit in Clang is
132385b113c3SChuanqi Xuto only import them in the implementation unit.
132485b113c3SChuanqi Xu
13259263318fSAaron BallmanKnown Issues
13269263318fSAaron Ballman------------
1327b1d5af81SChuanqi Xu
13289263318fSAaron BallmanThe following describes issues in the current implementation of modules. Please
13299263318fSAaron Ballmansee
13309263318fSAaron Ballman`the issues list for modules <https://github.com/llvm/llvm-project/labels/clang%3Amodules>`_
13319263318fSAaron Ballmanfor a list of issues or to file a new issue if you don't find an existing one.
13329263318fSAaron BallmanWhen creating a new issue for standard C++ modules, please start the title with
13339263318fSAaron Ballman``[C++20] [Modules]`` (or ``[C++23] [Modules]``, etc) and add the label
13349263318fSAaron Ballman``clang:modules`` if possible.
1335b1d5af81SChuanqi Xu
13369263318fSAaron BallmanA high-level overview of support for standards features, including modules, can
13379263318fSAaron Ballmanbe found on the `C++ Feature Status <https://clang.llvm.org/cxx_status.html>`_
13389263318fSAaron Ballmanpage.
1339b1d5af81SChuanqi Xu
13409263318fSAaron BallmanIncluding headers after import is not well-supported
13419263318fSAaron Ballman~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1342684955a2SChuanqi Xu
13439263318fSAaron BallmanThe following example is accepted:
1344684955a2SChuanqi Xu
1345684955a2SChuanqi Xu.. code-block:: c++
1346684955a2SChuanqi Xu
1347684955a2SChuanqi Xu  #include <iostream>
1348684955a2SChuanqi Xu  import foo; // assume module 'foo' contain the declarations from `<iostream>`
1349684955a2SChuanqi Xu
1350684955a2SChuanqi Xu  int main(int argc, char *argv[])
1351684955a2SChuanqi Xu  {
1352684955a2SChuanqi Xu      std::cout << "Test\n";
1353684955a2SChuanqi Xu      return 0;
1354684955a2SChuanqi Xu  }
1355684955a2SChuanqi Xu
13569263318fSAaron Ballmanbut if the order of ``#include <iostream>`` and ``import foo;`` is reversed,
13579263318fSAaron Ballmanthen the code is currently rejected:
1358684955a2SChuanqi Xu
1359684955a2SChuanqi Xu.. code-block:: c++
1360684955a2SChuanqi Xu
1361684955a2SChuanqi Xu  import foo; // assume module 'foo' contain the declarations from `<iostream>`
1362684955a2SChuanqi Xu  #include <iostream>
1363684955a2SChuanqi Xu
1364684955a2SChuanqi Xu  int main(int argc, char *argv[])
1365684955a2SChuanqi Xu  {
1366684955a2SChuanqi Xu      std::cout << "Test\n";
1367684955a2SChuanqi Xu      return 0;
1368684955a2SChuanqi Xu  }
1369684955a2SChuanqi Xu
1370684955a2SChuanqi XuBoth of the above examples should be accepted.
1371684955a2SChuanqi Xu
13729263318fSAaron BallmanThis is a limitation of the implementation. In the first example, the compiler
13739263318fSAaron Ballmanwill see and parse ``<iostream>`` first then it will see the ``import``. In
13749263318fSAaron Ballmanthis case, ODR checking and declaration merging will happen in the
13759263318fSAaron Ballmandeserializer. In the second example, the compiler will see the ``import`` first
13769263318fSAaron Ballmanand the ``#include`` second which results in ODR checking and declarations
13779263318fSAaron Ballmanmerging happening in the semantic analyzer. This is due to a divergence in the
13789263318fSAaron Ballmanimplementation path. This is tracked by
13799263318fSAaron Ballman`#61465 <https://github.com/llvm/llvm-project/issues/61465>`_.
1380684955a2SChuanqi Xu
13819263318fSAaron BallmanIgnored ``preferred_name`` Attribute
13829263318fSAaron Ballman~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1383684955a2SChuanqi Xu
13849263318fSAaron BallmanWhen Clang writes BMIs, it will ignore the ``preferred_name`` attribute on
13859263318fSAaron Ballmandeclarations which use it. Thus, the preferred name will not be displayed in
13869263318fSAaron Ballmanthe debugger as expected. This is tracked by
13879263318fSAaron Ballman`#56490 <https://github.com/llvm/llvm-project/issues/56490>`_.
1388b1d5af81SChuanqi Xu
1389b1d5af81SChuanqi XuDon't emit macros about module declaration
1390b1d5af81SChuanqi Xu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1391b1d5af81SChuanqi Xu
13929263318fSAaron BallmanThis is covered by `P1857R3 <https://wg21.link/P1857R3>`_. It is mentioned here
13939263318fSAaron Ballmanbecause we want users to be aware that we don't yet implement it.
1394b1d5af81SChuanqi Xu
13959263318fSAaron BallmanA direct approach to write code that can be compiled by both modules and
13969263318fSAaron Ballmannon-module builds may look like:
1397b1d5af81SChuanqi Xu
1398b1d5af81SChuanqi Xu.. code-block:: c++
1399b1d5af81SChuanqi Xu
1400b1d5af81SChuanqi Xu  MODULE
1401b1d5af81SChuanqi Xu  IMPORT header_name
1402b1d5af81SChuanqi Xu  EXPORT_MODULE MODULE_NAME;
1403b1d5af81SChuanqi Xu  IMPORT header_name
1404b1d5af81SChuanqi Xu  EXPORT ...
1405b1d5af81SChuanqi Xu
14069263318fSAaron BallmanThe intent of this is that this file can be compiled like a module unit or a
14079263318fSAaron Ballmannon-module unit depending on the definition of some macros. However, this usage
14089263318fSAaron Ballmanis forbidden by P1857R3 which is not yet implemented in Clang. This means that
14099263318fSAaron Ballmanis possible to write invalid modules which will no longer be accepted once
14109263318fSAaron BallmanP1857R3 is implemented. This is tracked by
1411ded6dd24Sh-vetinari`#54047 <https://github.com/llvm/llvm-project/issues/54047>`_.
1412b1d5af81SChuanqi Xu
14139263318fSAaron BallmanUntil then, it is recommended not to mix macros with module declarations.
14149263318fSAaron Ballman
1415b1d5af81SChuanqi Xu
1416b1d5af81SChuanqi XuIn consistent filename suffix requirement for importable module units
1417b1d5af81SChuanqi Xu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1418b1d5af81SChuanqi Xu
14199263318fSAaron BallmanCurrently, Clang requires the file name of an ``importable module unit`` to
14209263318fSAaron Ballmanhave ``.cppm`` (or ``.ccm``, ``.cxxm``, ``.c++m``) as the file extension.
14219263318fSAaron BallmanHowever, the behavior is inconsistent with other compilers. This is tracked by
14229263318fSAaron Ballman`#57416 <https://github.com/llvm/llvm-project/issues/57416>`_.
1423b1d5af81SChuanqi Xu
14249263318fSAaron BallmanIncorrect ODR violation diagnostics
14259263318fSAaron Ballman~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14263b48613fSChuanqi Xu
14279263318fSAaron BallmanODR violations are a common issue when using modules. Clang sometimes produces
14289263318fSAaron Ballmanfalse-positive diagnostics or fails to produce true-positive diagnostics of the
14299263318fSAaron BallmanOne Definition Rule. One often-reported example is:
1430a31a6007SChuanqi Xu
1431a31a6007SChuanqi Xu.. code-block:: c++
1432a31a6007SChuanqi Xu
1433a31a6007SChuanqi Xu  // part.cc
1434a31a6007SChuanqi Xu  module;
1435a31a6007SChuanqi Xu  typedef long T;
1436a31a6007SChuanqi Xu  namespace ns {
1437a31a6007SChuanqi Xu  inline void fun() {
1438a31a6007SChuanqi Xu      (void)(T)0;
1439a31a6007SChuanqi Xu  }
1440a31a6007SChuanqi Xu  }
1441a31a6007SChuanqi Xu  export module repro:part;
1442a31a6007SChuanqi Xu
1443a31a6007SChuanqi Xu  // repro.cc
1444a31a6007SChuanqi Xu  module;
1445a31a6007SChuanqi Xu  typedef long T;
1446a31a6007SChuanqi Xu  namespace ns {
1447a31a6007SChuanqi Xu      using ::T;
1448a31a6007SChuanqi Xu  }
1449a31a6007SChuanqi Xu  namespace ns {
1450a31a6007SChuanqi Xu  inline void fun() {
1451a31a6007SChuanqi Xu      (void)(T)0;
1452a31a6007SChuanqi Xu  }
1453a31a6007SChuanqi Xu  }
1454a31a6007SChuanqi Xu  export module repro;
1455a31a6007SChuanqi Xu  export import :part;
1456a31a6007SChuanqi Xu
14579263318fSAaron BallmanCurrently the compiler incorrectly diagnoses the inconsistent definition of
14589263318fSAaron Ballman``fun()`` in two module units. Because both definitions of ``fun()`` have the
14599263318fSAaron Ballmansame spelling and ``T`` refers to the same type entity, there is no ODR
14609263318fSAaron Ballmanviolation. This is tracked by
14619263318fSAaron Ballman`#78850 <https://github.com/llvm/llvm-project/issues/78850>`_.
1462a31a6007SChuanqi Xu
1463a31a6007SChuanqi XuUsing TU-local entity in other units
1464a31a6007SChuanqi Xu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1465a31a6007SChuanqi Xu
14669263318fSAaron BallmanModule units are translation units, so the entities which should be local to
14679263318fSAaron Ballmanthe module unit itself should never be used by other units.
1468a31a6007SChuanqi Xu
14699263318fSAaron BallmanThe C++ standard defines the concept of ``TU-local`` and ``exposure`` in
1470a31a6007SChuanqi Xu`basic.link/p14 <https://eel.is/c++draft/basic.link#14>`_,
1471a31a6007SChuanqi Xu`basic.link/p15 <https://eel.is/c++draft/basic.link#15>`_,
1472a31a6007SChuanqi Xu`basic.link/p16 <https://eel.is/c++draft/basic.link#16>`_,
14739263318fSAaron Ballman`basic.link/p17 <https://eel.is/c++draft/basic.link#17>`_, and
1474a31a6007SChuanqi Xu`basic.link/p18 <https://eel.is/c++draft/basic.link#18>`_.
1475a31a6007SChuanqi Xu
14769263318fSAaron BallmanHowever, Clang doesn't formally support these two concepts. This results in
14779263318fSAaron Ballmanunclear or confusing diagnostic messages. Further, Clang may import
14789263318fSAaron Ballman``TU-local`` entities to other units without any diagnostics. This is tracked
14799263318fSAaron Ballmanby `#78173 <https://github.com/llvm/llvm-project/issues/78173>`_.
1480a31a6007SChuanqi Xu
14819263318fSAaron Ballman.. _header-units:
1482be72dca5SChuanqi Xu
1483b1d5af81SChuanqi XuHeader Units
1484b1d5af81SChuanqi Xu============
1485b1d5af81SChuanqi Xu
14869263318fSAaron BallmanHow to build projects using header units
14879263318fSAaron Ballman----------------------------------------
1488b1d5af81SChuanqi Xu
148920d9aa1aSChuanqi Xu.. warning::
149020d9aa1aSChuanqi Xu
14919263318fSAaron Ballman   The support for header units, including related command line options, is
14929263318fSAaron Ballman   experimental. There are still many unanswered question about how tools
14939263318fSAaron Ballman   should interact with header units. The details described here may change in
14949263318fSAaron Ballman   the future.
149520d9aa1aSChuanqi Xu
1496b1d5af81SChuanqi XuQuick Start
1497b1d5af81SChuanqi Xu~~~~~~~~~~~
1498b1d5af81SChuanqi Xu
14999263318fSAaron BallmanThe following example:
1500b1d5af81SChuanqi Xu
1501b1d5af81SChuanqi Xu.. code-block:: c++
1502b1d5af81SChuanqi Xu
1503b1d5af81SChuanqi Xu  import <iostream>;
1504b1d5af81SChuanqi Xu  int main() {
1505b1d5af81SChuanqi Xu    std::cout << "Hello World.\n";
1506b1d5af81SChuanqi Xu  }
1507b1d5af81SChuanqi Xu
15089263318fSAaron Ballmancould be compiled with:
1509b1d5af81SChuanqi Xu
1510b1d5af81SChuanqi Xu.. code-block:: console
1511b1d5af81SChuanqi Xu
1512b1d5af81SChuanqi Xu  $ clang++ -std=c++20 -xc++-system-header --precompile iostream -o iostream.pcm
1513b1d5af81SChuanqi Xu  $ clang++ -std=c++20 -fmodule-file=iostream.pcm main.cpp
1514b1d5af81SChuanqi Xu
1515b1d5af81SChuanqi XuHow to produce BMIs
1516b1d5af81SChuanqi Xu~~~~~~~~~~~~~~~~~~~
1517b1d5af81SChuanqi Xu
15189263318fSAaron BallmanSimilar to named modules, ``--precompile`` can be used to produce a BMI.
15199263318fSAaron BallmanHowever, that requires specifying that the input file is a header by using
15209263318fSAaron Ballman``-xc++-system-header`` or ``-xc++-user-header``.
1521b1d5af81SChuanqi Xu
15229263318fSAaron BallmanThe ``-fmodule-header={user,system}`` option can also be used to produce a BMI
15239263318fSAaron Ballmanfor header units which have a file extension like `.h` or `.hh`. The argument to
15249263318fSAaron Ballman``-fmodule-header`` specifies either the user search path or the system search
15259263318fSAaron Ballmanpath. The default value for ``-fmodule-header`` is ``user``. For example:
1526b1d5af81SChuanqi Xu
1527b1d5af81SChuanqi Xu.. code-block:: c++
1528b1d5af81SChuanqi Xu
1529b1d5af81SChuanqi Xu  // foo.h
1530b1d5af81SChuanqi Xu  #include <iostream>
1531b1d5af81SChuanqi Xu  void Hello() {
1532b1d5af81SChuanqi Xu    std::cout << "Hello World.\n";
1533b1d5af81SChuanqi Xu  }
1534b1d5af81SChuanqi Xu
1535b1d5af81SChuanqi Xu  // use.cpp
1536b1d5af81SChuanqi Xu  import "foo.h";
1537b1d5af81SChuanqi Xu  int main() {
1538b1d5af81SChuanqi Xu    Hello();
1539b1d5af81SChuanqi Xu  }
1540b1d5af81SChuanqi Xu
15419263318fSAaron Ballmancould be compiled with:
1542b1d5af81SChuanqi Xu
1543b1d5af81SChuanqi Xu.. code-block:: console
1544b1d5af81SChuanqi Xu
1545b1d5af81SChuanqi Xu  $ clang++ -std=c++20 -fmodule-header foo.h -o foo.pcm
1546b1d5af81SChuanqi Xu  $ clang++ -std=c++20 -fmodule-file=foo.pcm use.cpp
1547b1d5af81SChuanqi Xu
15489263318fSAaron BallmanFor headers which do not have a file extension, ``-xc++-header`` (or
15499263318fSAaron Ballman``-xc++-system-header``, ``-xc++-user-header``) must be used to specify the
15509263318fSAaron Ballmanfile as a header. For example:
1551b1d5af81SChuanqi Xu
1552b1d5af81SChuanqi Xu.. code-block:: c++
1553b1d5af81SChuanqi Xu
1554b1d5af81SChuanqi Xu  // use.cpp
1555b1d5af81SChuanqi Xu  import "foo.h";
1556b1d5af81SChuanqi Xu  int main() {
1557b1d5af81SChuanqi Xu    Hello();
1558b1d5af81SChuanqi Xu  }
1559b1d5af81SChuanqi Xu
1560b1d5af81SChuanqi Xu.. code-block:: console
1561b1d5af81SChuanqi Xu
1562b1d5af81SChuanqi Xu  $ clang++ -std=c++20 -fmodule-header=system -xc++-header iostream -o iostream.pcm
1563b1d5af81SChuanqi Xu  $ clang++ -std=c++20 -fmodule-file=iostream.pcm use.cpp
1564b1d5af81SChuanqi Xu
15659263318fSAaron BallmanHow to specify dependent BMIs
15669263318fSAaron Ballman~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1567b1d5af81SChuanqi Xu
15689263318fSAaron Ballman``-fmodule-file`` can be used to specify a dependent BMI (or multiple times for
15699263318fSAaron Ballmanmore than one dependent BMI).
1570b1d5af81SChuanqi Xu
15719263318fSAaron BallmanWith the existing implementation, ``-fprebuilt-module-path`` cannot be used for
15729263318fSAaron Ballmanheader units (because they are nominally anonymous). For header units, use
15739263318fSAaron Ballman``-fmodule-file`` to include the relevant PCM file for each header unit.
1574b1d5af81SChuanqi Xu
15759263318fSAaron BallmanThis is expect to be solved in a future version of Clang either by the compiler
15769263318fSAaron Ballmanfinding and specifying ``-fmodule-file`` automatically, or by the use of a
15779263318fSAaron Ballmanmodule-mapper that understands how to map the header name to their PCMs.
1578b1d5af81SChuanqi Xu
15799263318fSAaron BallmanCompiling a header unit to an object file
15809263318fSAaron Ballman~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1581b1d5af81SChuanqi Xu
15829263318fSAaron BallmanA header unit cannot be compiled to an object file due to the semantics of
15839263318fSAaron Ballmanheader units. For example:
1584b1d5af81SChuanqi Xu
1585b1d5af81SChuanqi Xu.. code-block:: console
1586b1d5af81SChuanqi Xu
1587b1d5af81SChuanqi Xu  $ clang++ -std=c++20 -xc++-system-header --precompile iostream -o iostream.pcm
1588b1d5af81SChuanqi Xu  # This is not allowed!
1589b1d5af81SChuanqi Xu  $ clang++ iostream.pcm -c -o iostream.o
1590b1d5af81SChuanqi Xu
1591b1d5af81SChuanqi XuInclude translation
1592b1d5af81SChuanqi Xu~~~~~~~~~~~~~~~~~~~
1593b1d5af81SChuanqi Xu
15949263318fSAaron BallmanThe C++ standard allows vendors to convert ``#include header-name`` to
15959263318fSAaron Ballman``import header-name;`` when possible. Currently, Clang does this translation
15969263318fSAaron Ballmanfor the ``#include`` in the global module fragment. For example, the following
15979263318fSAaron Ballmanexample:
1598b1d5af81SChuanqi Xu
1599b1d5af81SChuanqi Xu.. code-block:: c++
1600b1d5af81SChuanqi Xu
1601b1d5af81SChuanqi Xu  module;
1602b1d5af81SChuanqi Xu  import <iostream>;
1603b1d5af81SChuanqi Xu  export module M;
1604b1d5af81SChuanqi Xu  export void Hello() {
1605b1d5af81SChuanqi Xu    std::cout << "Hello.\n";
1606b1d5af81SChuanqi Xu  }
1607b1d5af81SChuanqi Xu
16089263318fSAaron Ballmanis the same as this example:
1609b1d5af81SChuanqi Xu
1610b1d5af81SChuanqi Xu.. code-block:: c++
1611b1d5af81SChuanqi Xu
1612b1d5af81SChuanqi Xu  module;
1613b1d5af81SChuanqi Xu  #include <iostream>
1614b1d5af81SChuanqi Xu  export module M;
1615b1d5af81SChuanqi Xu  export void Hello() {
1616b1d5af81SChuanqi Xu      std::cout << "Hello.\n";
1617b1d5af81SChuanqi Xu  }
1618b1d5af81SChuanqi Xu
1619b1d5af81SChuanqi Xu.. code-block:: console
1620b1d5af81SChuanqi Xu
1621b1d5af81SChuanqi Xu  $ clang++ -std=c++20 -xc++-system-header --precompile iostream -o iostream.pcm
1622b1d5af81SChuanqi Xu  $ clang++ -std=c++20 -fmodule-file=iostream.pcm --precompile M.cppm -o M.cpp
1623b1d5af81SChuanqi Xu
16249263318fSAaron BallmanIn the latter example, Clang can find the BMI for ``<iostream>`` and so it
16259263318fSAaron Ballmantries to replace the ``#include <iostream>`` with ``import <iostream>;``
16269263318fSAaron Ballmanautomatically.
1627b1d5af81SChuanqi Xu
1628b1d5af81SChuanqi Xu
16299263318fSAaron BallmanDifferences between Clang modules and header units
16309263318fSAaron Ballman--------------------------------------------------
1631b1d5af81SChuanqi Xu
16329263318fSAaron BallmanHeader units have similar semantics to Clang modules. The semantics of both are
16339263318fSAaron Ballmanlike headers. Therefore, header units can be mimicked by Clang modules as in
16349263318fSAaron Ballmanthe following example:
1635b1d5af81SChuanqi Xu
1636b1d5af81SChuanqi Xu.. code-block:: c++
1637b1d5af81SChuanqi Xu
1638b1d5af81SChuanqi Xu  module "iostream" {
1639b1d5af81SChuanqi Xu    export *
1640b1d5af81SChuanqi Xu    header "/path/to/libstdcxx/iostream"
1641b1d5af81SChuanqi Xu  }
1642b1d5af81SChuanqi Xu
1643b1d5af81SChuanqi Xu.. code-block:: console
1644b1d5af81SChuanqi Xu
1645b1d5af81SChuanqi Xu  $ clang++ -std=c++20 -fimplicit-modules -fmodule-map-file=.modulemap main.cpp
1646b1d5af81SChuanqi Xu
16479263318fSAaron BallmanThis example is simplified when using libc++:
1648b1d5af81SChuanqi Xu
1649b1d5af81SChuanqi Xu.. code-block:: console
1650b1d5af81SChuanqi Xu
1651b1d5af81SChuanqi Xu  $ clang++ -std=c++20 main.cpp -fimplicit-modules -fimplicit-module-maps
1652b1d5af81SChuanqi Xu
16539263318fSAaron Ballmanbecause libc++ already supplies a
16549263318fSAaron Ballman`module map <https://github.com/llvm/llvm-project/blob/main/libcxx/include/module.modulemap.in>`_.
1655b1d5af81SChuanqi Xu
16569263318fSAaron BallmanThis raises the question: why are header units not implemented through Clang
16579263318fSAaron Ballmanmodules?
1658b1d5af81SChuanqi Xu
16599263318fSAaron BallmanThis is primarily because Clang modules have more hierarchical semantics when
16609263318fSAaron Ballmanwrapping multiple headers together as one module, which is not supported by
16619263318fSAaron BallmanStandard C++ Header units. We want to avoid the impression that these
16629263318fSAaron Ballmanadditional semantics get interpreted as Standard C++ behavior.
1663b1d5af81SChuanqi Xu
16649263318fSAaron BallmanAnother reason is that there are proposals to introduce module mappers to the
16659263318fSAaron BallmanC++ standard (for example, https://wg21.link/p1184r2). Reusing Clang's
16669263318fSAaron Ballman``modulemap`` may be more difficult if we need to introduce another module
16679263318fSAaron Ballmanmapper.
1668b1d5af81SChuanqi Xu
16699263318fSAaron BallmanDiscovering Dependencies
16709263318fSAaron Ballman========================
1671b1d5af81SChuanqi Xu
16729263318fSAaron BallmanWithout use of modules, all the translation units in a project can be compiled
16739263318fSAaron Ballmanin parallel. However, the presence of module units requires compiling the
16749263318fSAaron Ballmantranslation units in a topological order.
16759c4f0d83SChuanqi Xu
16769263318fSAaron BallmanThe ``clang-scan-deps`` tool can extract dependency information and produce a
16779263318fSAaron BallmanJSON file conforming to the specification described in
16789263318fSAaron Ballman`P1689 <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1689r5.html>`_.
16799263318fSAaron BallmanOnly named modules are supported currently.
16809c4f0d83SChuanqi Xu
16819263318fSAaron BallmanA compilation database is needed when using ``clang-scan-deps``. See
16829c4f0d83SChuanqi Xu`JSON Compilation Database Format Specification <JSONCompilationDatabase.html>`_
16839263318fSAaron Ballmanfor more information about compilation databases. Note that the ``output``
16849263318fSAaron BallmanJSON attribute is necessary for ``clang-scan-deps`` to scan using the P1689
16859263318fSAaron Ballmanformat. For example:
16869c4f0d83SChuanqi Xu
16879c4f0d83SChuanqi Xu.. code-block:: c++
16889c4f0d83SChuanqi Xu
16899c4f0d83SChuanqi Xu  //--- M.cppm
16909c4f0d83SChuanqi Xu  export module M;
16919c4f0d83SChuanqi Xu  export import :interface_part;
16929c4f0d83SChuanqi Xu  import :impl_part;
16939c4f0d83SChuanqi Xu  export int Hello();
16949c4f0d83SChuanqi Xu
16959c4f0d83SChuanqi Xu  //--- interface_part.cppm
16969c4f0d83SChuanqi Xu  export module M:interface_part;
16979c4f0d83SChuanqi Xu  export void World();
16989c4f0d83SChuanqi Xu
16999c4f0d83SChuanqi Xu  //--- Impl.cpp
17009c4f0d83SChuanqi Xu  module;
17019c4f0d83SChuanqi Xu  #include <iostream>
17029c4f0d83SChuanqi Xu  module M;
17039c4f0d83SChuanqi Xu  void Hello() {
17049c4f0d83SChuanqi Xu      std::cout << "Hello ";
17059c4f0d83SChuanqi Xu  }
17069c4f0d83SChuanqi Xu
17079c4f0d83SChuanqi Xu  //--- impl_part.cppm
17089c4f0d83SChuanqi Xu  module;
17099c4f0d83SChuanqi Xu  #include <string>
17109c4f0d83SChuanqi Xu  #include <iostream>
17119c4f0d83SChuanqi Xu  module M:impl_part;
17129c4f0d83SChuanqi Xu  import :interface_part;
17139c4f0d83SChuanqi Xu
17149c4f0d83SChuanqi Xu  std::string W = "World.";
17159c4f0d83SChuanqi Xu  void World() {
17169c4f0d83SChuanqi Xu      std::cout << W << std::endl;
17179c4f0d83SChuanqi Xu  }
17189c4f0d83SChuanqi Xu
17199c4f0d83SChuanqi Xu  //--- User.cpp
17209c4f0d83SChuanqi Xu  import M;
17219c4f0d83SChuanqi Xu  import third_party_module;
17229c4f0d83SChuanqi Xu  int main() {
17239c4f0d83SChuanqi Xu    Hello();
17249c4f0d83SChuanqi Xu    World();
17259c4f0d83SChuanqi Xu    return 0;
17269c4f0d83SChuanqi Xu  }
17279c4f0d83SChuanqi Xu
17289c4f0d83SChuanqi XuAnd here is the compilation database:
17299c4f0d83SChuanqi Xu
17309c4f0d83SChuanqi Xu.. code-block:: text
17319c4f0d83SChuanqi Xu
17329c4f0d83SChuanqi Xu  [
17339c4f0d83SChuanqi Xu  {
17349c4f0d83SChuanqi Xu      "directory": ".",
17359c4f0d83SChuanqi Xu      "command": "<path-to-compiler-executable>/clang++ -std=c++20 M.cppm -c -o M.o",
17369c4f0d83SChuanqi Xu      "file": "M.cppm",
17379c4f0d83SChuanqi Xu      "output": "M.o"
17389c4f0d83SChuanqi Xu  },
17399c4f0d83SChuanqi Xu  {
17409c4f0d83SChuanqi Xu      "directory": ".",
17419c4f0d83SChuanqi Xu      "command": "<path-to-compiler-executable>/clang++ -std=c++20 Impl.cpp -c -o Impl.o",
17429c4f0d83SChuanqi Xu      "file": "Impl.cpp",
17439c4f0d83SChuanqi Xu      "output": "Impl.o"
17449c4f0d83SChuanqi Xu  },
17459c4f0d83SChuanqi Xu  {
17469c4f0d83SChuanqi Xu      "directory": ".",
17479c4f0d83SChuanqi Xu      "command": "<path-to-compiler-executable>/clang++ -std=c++20 impl_part.cppm -c -o impl_part.o",
17489c4f0d83SChuanqi Xu      "file": "impl_part.cppm",
17499c4f0d83SChuanqi Xu      "output": "impl_part.o"
17509c4f0d83SChuanqi Xu  },
17519c4f0d83SChuanqi Xu  {
17529c4f0d83SChuanqi Xu      "directory": ".",
17539c4f0d83SChuanqi Xu      "command": "<path-to-compiler-executable>/clang++ -std=c++20 interface_part.cppm -c -o interface_part.o",
17549c4f0d83SChuanqi Xu      "file": "interface_part.cppm",
17559c4f0d83SChuanqi Xu      "output": "interface_part.o"
17569c4f0d83SChuanqi Xu  },
17579c4f0d83SChuanqi Xu  {
17589c4f0d83SChuanqi Xu      "directory": ".",
17599c4f0d83SChuanqi Xu      "command": "<path-to-compiler-executable>/clang++ -std=c++20 User.cpp -c -o User.o",
17609c4f0d83SChuanqi Xu      "file": "User.cpp",
17619c4f0d83SChuanqi Xu      "output": "User.o"
17629c4f0d83SChuanqi Xu  }
17639c4f0d83SChuanqi Xu  ]
17649c4f0d83SChuanqi Xu
17659263318fSAaron BallmanTo get the dependency information in P1689 format, use:
17669c4f0d83SChuanqi Xu
17679c4f0d83SChuanqi Xu.. code-block:: console
17689c4f0d83SChuanqi Xu
17699c4f0d83SChuanqi Xu  $ clang-scan-deps -format=p1689 -compilation-database P1689.json
17709c4f0d83SChuanqi Xu
17719263318fSAaron Ballmanto get:
17729c4f0d83SChuanqi Xu
17739c4f0d83SChuanqi Xu.. code-block:: text
17749c4f0d83SChuanqi Xu
17759c4f0d83SChuanqi Xu  {
17769c4f0d83SChuanqi Xu    "revision": 0,
17779c4f0d83SChuanqi Xu    "rules": [
17789c4f0d83SChuanqi Xu      {
17799c4f0d83SChuanqi Xu        "primary-output": "Impl.o",
17809c4f0d83SChuanqi Xu        "requires": [
17819c4f0d83SChuanqi Xu          {
17829c4f0d83SChuanqi Xu            "logical-name": "M",
17839c4f0d83SChuanqi Xu            "source-path": "M.cppm"
17849c4f0d83SChuanqi Xu          }
17859c4f0d83SChuanqi Xu        ]
17869c4f0d83SChuanqi Xu      },
17879c4f0d83SChuanqi Xu      {
17889c4f0d83SChuanqi Xu        "primary-output": "M.o",
17899c4f0d83SChuanqi Xu        "provides": [
17909c4f0d83SChuanqi Xu          {
17919c4f0d83SChuanqi Xu            "is-interface": true,
17929c4f0d83SChuanqi Xu            "logical-name": "M",
17939c4f0d83SChuanqi Xu            "source-path": "M.cppm"
17949c4f0d83SChuanqi Xu          }
17959c4f0d83SChuanqi Xu        ],
17969c4f0d83SChuanqi Xu        "requires": [
17979c4f0d83SChuanqi Xu          {
17989c4f0d83SChuanqi Xu            "logical-name": "M:interface_part",
17999c4f0d83SChuanqi Xu            "source-path": "interface_part.cppm"
18009c4f0d83SChuanqi Xu          },
18019c4f0d83SChuanqi Xu          {
18029c4f0d83SChuanqi Xu            "logical-name": "M:impl_part",
18039c4f0d83SChuanqi Xu            "source-path": "impl_part.cppm"
18049c4f0d83SChuanqi Xu          }
18059c4f0d83SChuanqi Xu        ]
18069c4f0d83SChuanqi Xu      },
18079c4f0d83SChuanqi Xu      {
18089c4f0d83SChuanqi Xu        "primary-output": "User.o",
18099c4f0d83SChuanqi Xu        "requires": [
18109c4f0d83SChuanqi Xu          {
18119c4f0d83SChuanqi Xu            "logical-name": "M",
18129c4f0d83SChuanqi Xu            "source-path": "M.cppm"
18139c4f0d83SChuanqi Xu          },
18149c4f0d83SChuanqi Xu          {
18159c4f0d83SChuanqi Xu            "logical-name": "third_party_module"
18169c4f0d83SChuanqi Xu          }
18179c4f0d83SChuanqi Xu        ]
18189c4f0d83SChuanqi Xu      },
18199c4f0d83SChuanqi Xu      {
18209c4f0d83SChuanqi Xu        "primary-output": "impl_part.o",
18219c4f0d83SChuanqi Xu        "provides": [
18229c4f0d83SChuanqi Xu          {
18239c4f0d83SChuanqi Xu            "is-interface": false,
18249c4f0d83SChuanqi Xu            "logical-name": "M:impl_part",
18259c4f0d83SChuanqi Xu            "source-path": "impl_part.cppm"
18269c4f0d83SChuanqi Xu          }
18279c4f0d83SChuanqi Xu        ],
18289c4f0d83SChuanqi Xu        "requires": [
18299c4f0d83SChuanqi Xu          {
18309c4f0d83SChuanqi Xu            "logical-name": "M:interface_part",
18319c4f0d83SChuanqi Xu            "source-path": "interface_part.cppm"
18329c4f0d83SChuanqi Xu          }
18339c4f0d83SChuanqi Xu        ]
18349c4f0d83SChuanqi Xu      },
18359c4f0d83SChuanqi Xu      {
18369c4f0d83SChuanqi Xu        "primary-output": "interface_part.o",
18379c4f0d83SChuanqi Xu        "provides": [
18389c4f0d83SChuanqi Xu          {
18399c4f0d83SChuanqi Xu            "is-interface": true,
18409c4f0d83SChuanqi Xu            "logical-name": "M:interface_part",
18419c4f0d83SChuanqi Xu            "source-path": "interface_part.cppm"
18429c4f0d83SChuanqi Xu          }
18439c4f0d83SChuanqi Xu        ]
18449c4f0d83SChuanqi Xu      }
18459c4f0d83SChuanqi Xu    ],
18469c4f0d83SChuanqi Xu    "version": 1
18479c4f0d83SChuanqi Xu  }
18489c4f0d83SChuanqi Xu
18499c4f0d83SChuanqi XuSee the P1689 paper for the meaning of the fields.
18509c4f0d83SChuanqi Xu
18519263318fSAaron BallmanGetting dependency information per file with finer-grained control (such as
18529263318fSAaron Ballmanscanning generated source files) is possible. For example:
18539c4f0d83SChuanqi Xu
18549c4f0d83SChuanqi Xu.. code-block:: console
18559c4f0d83SChuanqi Xu
18569c4f0d83SChuanqi Xu  $ clang-scan-deps -format=p1689 -- <path-to-compiler-executable>/clang++ -std=c++20 impl_part.cppm -c -o impl_part.o
18579c4f0d83SChuanqi Xu
18589263318fSAaron Ballmanwill produce:
18599c4f0d83SChuanqi Xu
18609c4f0d83SChuanqi Xu.. code-block:: text
18619c4f0d83SChuanqi Xu
18629c4f0d83SChuanqi Xu  {
18639c4f0d83SChuanqi Xu    "revision": 0,
18649c4f0d83SChuanqi Xu    "rules": [
18659c4f0d83SChuanqi Xu      {
18669c4f0d83SChuanqi Xu        "primary-output": "impl_part.o",
18679c4f0d83SChuanqi Xu        "provides": [
18689c4f0d83SChuanqi Xu          {
18699c4f0d83SChuanqi Xu            "is-interface": false,
18709c4f0d83SChuanqi Xu            "logical-name": "M:impl_part",
18719c4f0d83SChuanqi Xu            "source-path": "impl_part.cppm"
18729c4f0d83SChuanqi Xu          }
18739c4f0d83SChuanqi Xu        ],
18749c4f0d83SChuanqi Xu        "requires": [
18759c4f0d83SChuanqi Xu          {
18769c4f0d83SChuanqi Xu            "logical-name": "M:interface_part"
18779c4f0d83SChuanqi Xu          }
18789c4f0d83SChuanqi Xu        ]
18799c4f0d83SChuanqi Xu      }
18809c4f0d83SChuanqi Xu    ],
18819c4f0d83SChuanqi Xu    "version": 1
18829c4f0d83SChuanqi Xu  }
18839c4f0d83SChuanqi Xu
18849263318fSAaron BallmanIndividual command line options can be specified after ``--``.
18859263318fSAaron Ballman``clang-scan-deps`` will extract the necessary information from the specified
18869263318fSAaron Ballmanoptions. Note that the path to the compiler executable needs to be specified
18879263318fSAaron Ballmanexplicitly instead of using ``clang++`` directly.
18889c4f0d83SChuanqi Xu
18899263318fSAaron BallmanUsers may want the scanner to get the transitional dependency information for
18909263318fSAaron Ballmanheaders. Otherwise, the project has to be scanned twice, once for headers and
18919263318fSAaron Ballmanonce for modules. To address this, ``clang-scan-deps`` will recognize the
18929263318fSAaron Ballmanspecified preprocessor options in the given command line and generate the
18939263318fSAaron Ballmancorresponding dependency information. For example:
18949c4f0d83SChuanqi Xu
18959c4f0d83SChuanqi Xu.. code-block:: console
18969c4f0d83SChuanqi Xu
18979c4f0d83SChuanqi Xu  $ clang-scan-deps -format=p1689 -- ../bin/clang++ -std=c++20 impl_part.cppm -c -o impl_part.o -MD -MT impl_part.ddi -MF impl_part.dep
18989c4f0d83SChuanqi Xu  $ cat impl_part.dep
18999c4f0d83SChuanqi Xu
19009263318fSAaron Ballmanwill produce:
19019c4f0d83SChuanqi Xu
19029c4f0d83SChuanqi Xu.. code-block:: text
19039c4f0d83SChuanqi Xu
19049c4f0d83SChuanqi Xu  impl_part.ddi: \
19059c4f0d83SChuanqi Xu    /usr/include/bits/wchar.h /usr/include/bits/types/wint_t.h \
19069c4f0d83SChuanqi Xu    /usr/include/bits/types/mbstate_t.h \
19079c4f0d83SChuanqi Xu    /usr/include/bits/types/__mbstate_t.h /usr/include/bits/types/__FILE.h \
19089c4f0d83SChuanqi Xu    /usr/include/bits/types/FILE.h /usr/include/bits/types/locale_t.h \
19099c4f0d83SChuanqi Xu    /usr/include/bits/types/__locale_t.h \
19109c4f0d83SChuanqi Xu    ...
19119c4f0d83SChuanqi Xu
19129263318fSAaron BallmanWhen ``clang-scan-deps`` detects the ``-MF`` option, it will try to write the
19132db08128SKazu Hiratadependency information for headers to the file specified by ``-MF``.
19149c4f0d83SChuanqi Xu
1915f6b94e00SChuanqi XuPossible Issues: Failed to find system headers
1916f6b94e00SChuanqi Xu----------------------------------------------
1917f6b94e00SChuanqi Xu
19189263318fSAaron BallmanIf encountering an error like ``fatal error: 'stddef.h' file not found``,
19199263318fSAaron Ballmanthe specified ``<path-to-compiler-executable>/clang++`` probably refers to a
19209263318fSAaron Ballmansymlink instead a real binary. There are four potential solutions to the
19219263318fSAaron Ballmanproblem:
1922f6b94e00SChuanqi Xu
19239263318fSAaron Ballman1. Point the specified compiler executable to the real binary instead of the
19249263318fSAaron Ballman   symlink.
19259263318fSAaron Ballman2. Invoke ``<path-to-compiler-executable>/clang++ -print-resource-dir`` to get
19269263318fSAaron Ballman   the corresponding resource directory for your compiler and add that
19279263318fSAaron Ballman   directory to the include search paths manually in the build scripts.
19289263318fSAaron Ballman3. For build systems that use a compilation database as the input for
19299263318fSAaron Ballman   ``clang-scan-deps``, the build system can add the
19309263318fSAaron Ballman   ``--resource-dir-recipe invoke-compiler`` option when executing
19319263318fSAaron Ballman   ``clang-scan-deps`` to calculate the resource directory dynamically.
1932f6b94e00SChuanqi Xu   The calculation happens only once for a unique ``<path-to-compiler-executable>/clang++``.
19339263318fSAaron Ballman4. For build systems that invoke ``clang-scan-deps`` per file, repeatedly
19349263318fSAaron Ballman   calculating the resource directory may be inefficient. In such cases, the
19359263318fSAaron Ballman   build system can cache the resource directory and specify
19369263318fSAaron Ballman   ``-resource-dir <resource-dir>`` explicitly, as in:
1937f6b94e00SChuanqi Xu
1938f6b94e00SChuanqi Xu   .. code-block:: console
1939f6b94e00SChuanqi Xu
1940f6b94e00SChuanqi Xu     $ clang-scan-deps -format=p1689 -- <path-to-compiler-executable>/clang++ -std=c++20 -resource-dir <resource-dir> mod.cppm -c -o mod.o
1941f6b94e00SChuanqi Xu
1942f6b94e00SChuanqi Xu
1943bae1adaeSChuanqi XuImport modules with clang-repl
1944bae1adaeSChuanqi Xu==============================
1945bae1adaeSChuanqi Xu
19469263318fSAaron Ballman``clang-repl`` supports importing C++20 named modules. For example:
1947bae1adaeSChuanqi Xu
1948bae1adaeSChuanqi Xu.. code-block:: c++
1949bae1adaeSChuanqi Xu
1950bae1adaeSChuanqi Xu  // M.cppm
1951bae1adaeSChuanqi Xu  export module M;
1952bae1adaeSChuanqi Xu  export const char* Hello() {
1953bae1adaeSChuanqi Xu      return "Hello Interpreter for Modules!";
1954bae1adaeSChuanqi Xu  }
1955bae1adaeSChuanqi Xu
19569263318fSAaron BallmanThe named module still needs to be compiled ahead of time.
1957bae1adaeSChuanqi Xu
1958bae1adaeSChuanqi Xu.. code-block:: console
1959bae1adaeSChuanqi Xu
1960bae1adaeSChuanqi Xu  $ clang++ -std=c++20 M.cppm --precompile -o M.pcm
1961bae1adaeSChuanqi Xu  $ clang++ M.pcm -c -o M.o
1962bae1adaeSChuanqi Xu  $ clang++ -shared M.o -o libM.so
1963bae1adaeSChuanqi Xu
19649263318fSAaron BallmanNote that the module unit needs to be compiled as a dynamic library so that
19659263318fSAaron Ballman``clang-repl`` can load the object files of the module units. Then it is
19669263318fSAaron Ballmanpossible to import module ``M`` in clang-repl.
1967bae1adaeSChuanqi Xu
1968bae1adaeSChuanqi Xu.. code-block:: console
1969bae1adaeSChuanqi Xu
1970bae1adaeSChuanqi Xu  $ clang-repl -Xcc=-std=c++20 -Xcc=-fprebuilt-module-path=.
1971bae1adaeSChuanqi Xu  # We need to load the dynamic library first before importing the modules.
1972bae1adaeSChuanqi Xu  clang-repl> %lib libM.so
1973bae1adaeSChuanqi Xu  clang-repl> import M;
1974bae1adaeSChuanqi Xu  clang-repl> extern "C" int printf(const char *, ...);
1975bae1adaeSChuanqi Xu  clang-repl> printf("%s\n", Hello());
1976bae1adaeSChuanqi Xu  Hello Interpreter for Modules!
1977bae1adaeSChuanqi Xu  clang-repl> %quit
1978bae1adaeSChuanqi Xu
1979b1d5af81SChuanqi XuPossible Questions
1980b1d5af81SChuanqi Xu==================
1981b1d5af81SChuanqi Xu
1982b1d5af81SChuanqi XuHow modules speed up compilation
1983b1d5af81SChuanqi Xu--------------------------------
1984b1d5af81SChuanqi Xu
19859263318fSAaron BallmanA classic theory for the reason why modules speed up the compilation is: if
19869263318fSAaron Ballmanthere are ``n`` headers and ``m`` source files and each header is included by
19879263318fSAaron Ballmaneach source file, then the complexity of the compilation is ``O(n*m)``.
19889263318fSAaron BallmanHowever, if there are ``n`` module interfaces and ``m`` source files, the
19899263318fSAaron Ballmancomplexity of the compilation is ``O(n+m)``. Therefore, using modules would be
19909263318fSAaron Ballmana significant improvement at scale. More simply, use of modules causes many of
19919263318fSAaron Ballmanthe redundant compilations to no longer be necessary.
1992b1d5af81SChuanqi Xu
19939263318fSAaron BallmanWhile this is accurate at a high level, this depends greatly on the
19949263318fSAaron Ballmanoptimization level, as illustrated below.
1995b1d5af81SChuanqi Xu
19969263318fSAaron BallmanFirst is ``-O0``. The compilation process is described in the following graph.
1997b1d5af81SChuanqi Xu
1998b1d5af81SChuanqi Xu.. code-block:: none
1999b1d5af81SChuanqi Xu
2000b1d5af81SChuanqi Xu  ├-------------frontend----------┼-------------middle end----------------┼----backend----┤
2001b1d5af81SChuanqi Xu  │                               │                                       │               │
2002b1d5af81SChuanqi Xu  └---parsing----sema----codegen--┴----- transformations ---- codegen ----┴---- codegen --┘
2003b1d5af81SChuanqi Xu
20049263318fSAaron Ballman  ├---------------------------------------------------------------------------------------┐
2005b1d5af81SChuanqi Xu  |                                                                                       │
2006b1d5af81SChuanqi Xu  |                                     source file                                       │
2007b1d5af81SChuanqi Xu  |                                                                                       │
2008b1d5af81SChuanqi Xu  └---------------------------------------------------------------------------------------┘
2009b1d5af81SChuanqi Xu
20109263318fSAaron Ballman              ├--------┐
2011b1d5af81SChuanqi Xu              │        │
2012b1d5af81SChuanqi Xu              │imported│
2013b1d5af81SChuanqi Xu              │        │
2014b1d5af81SChuanqi Xu              │  code  │
2015b1d5af81SChuanqi Xu              │        │
2016b1d5af81SChuanqi Xu              └--------┘
2017b1d5af81SChuanqi Xu
20189263318fSAaron BallmanIn this case, the source file (which could be a non-module unit or a module
20199263318fSAaron Ballmanunit) would get processed by the entire pipeline. However, the imported code
20209263318fSAaron Ballmanwould only get involved in semantic analysis, which, for the most part, is name
20219263318fSAaron Ballmanlookup, overload resolution, and template instantiation. All of these processes
20229263318fSAaron Ballmanare fast relative to the whole compilation process. More importantly, the
20239263318fSAaron Ballmanimported code only needs to be processed once during frontend code generation,
20249263318fSAaron Ballmanas well as the whole middle end and backend. So we could get a big win for the
20259263318fSAaron Ballmancompilation time in ``-O0``.
2026b1d5af81SChuanqi Xu
20279263318fSAaron BallmanBut with optimizations, things are different (the ``code generation`` part for
20289263318fSAaron Ballmaneach end is omitted due to limited space):
2029b1d5af81SChuanqi Xu
2030b1d5af81SChuanqi Xu.. code-block:: none
2031b1d5af81SChuanqi Xu
2032b1d5af81SChuanqi Xu  ├-------- frontend ---------┼--------------- middle end --------------------┼------ backend ----┤
2033b1d5af81SChuanqi Xu  │                           │                                               │                   │
2034b1d5af81SChuanqi Xu  └--- parsing ---- sema -----┴--- optimizations --- IPO ---- optimizations---┴--- optimizations -┘
2035b1d5af81SChuanqi Xu
20369263318fSAaron Ballman  ├-----------------------------------------------------------------------------------------------┐
2037b1d5af81SChuanqi Xu  │                                                                                               │
2038b1d5af81SChuanqi Xu  │                                         source file                                           │
2039b1d5af81SChuanqi Xu  │                                                                                               │
2040b1d5af81SChuanqi Xu  └-----------------------------------------------------------------------------------------------┘
20419263318fSAaron Ballman                ├---------------------------------------┐
2042b1d5af81SChuanqi Xu                │                                       │
2043b1d5af81SChuanqi Xu                │                                       │
2044b1d5af81SChuanqi Xu                │            imported code              │
2045b1d5af81SChuanqi Xu                │                                       │
2046b1d5af81SChuanqi Xu                │                                       │
2047b1d5af81SChuanqi Xu                └---------------------------------------┘
2048b1d5af81SChuanqi Xu
20499263318fSAaron BallmanIt would be very unfortunate if we end up with worse performance when using
20509263318fSAaron Ballmanmodules. The main concern is that when a source file is compiled, the compiler
20519263318fSAaron Ballmanneeds to see the body of imported module units so that it can perform IPO
20529263318fSAaron Ballman(InterProcedural Optimization, primarily inlining in practice) to optimize
20539263318fSAaron Ballmanfunctions in the current source file with the help of the information provided
20549263318fSAaron Ballmanby the imported module units. In other words, the imported code would be
20559263318fSAaron Ballmanprocessed again and again in importee units by optimizations (including IPO
20569263318fSAaron Ballmanitself). The optimizations before IPO and IPO itself are the most time-consuming
20579263318fSAaron Ballmanpart in whole compilation process. So from this perspective, it might not be
20589263318fSAaron Ballmanpossible to get the compile time improvements described, but there could be
20599263318fSAaron Ballmantime savings for optimizations after IPO and the whole backend.
2060b1d5af81SChuanqi Xu
20619263318fSAaron BallmanOverall, at ``-O0`` the implementations of functions defined in a module will
20629263318fSAaron Ballmannot impact module users, but at higher optimization levels the definitions of
20639263318fSAaron Ballmansuch functions are provided to user compilations for the purposes of
20649263318fSAaron Ballmanoptimization (but definitions of these functions are still not included in the
20659263318fSAaron Ballmanuse's object file). This means the build speedup at higher optimization levels
20669263318fSAaron Ballmanmay be lower than expected given ``-O0`` experience, but does provide more
20679263318fSAaron Ballmanoptimization opportunities.
2068b1d5af81SChuanqi Xu
2069e12b627aSChuanqi XuInteroperability with Clang Modules
2070e12b627aSChuanqi Xu-----------------------------------
2071e12b627aSChuanqi Xu
20729263318fSAaron BallmanWe **wish** to support Clang modules and standard C++ modules at the same time,
20739263318fSAaron Ballmanbut the mixing them together is not well used/tested yet. Please file new
20749263318fSAaron BallmanGitHub issues as you find interoperability problems.
2075