Skip to content

Commit 71e108c

Browse files
author
Alexandre Rames
committed
Allow searching for prebuilt implicit modules.
The behavior is controlled by the `-fprebuilt-implicit-modules` option, and allows searching for implicit modules in the prebuilt module cache paths. The current command-line options for prebuilt modules do not allow to easily maintain and use multiple versions of modules. Both the producer and users of prebuilt modules are required to know the relationships between compilation options and module file paths. Using a particular version of a prebuilt module requires passing a particular option on the command line (e.g. `-fmodule-file=[<name>=]<file>` or `-fprebuilt-module-path=<directory>`). However the compiler already knows how to distinguish and automatically locate implicit modules. Hence this proposal to introduce the `-fprebuilt-implicit-modules` option. When set, it enables searching for implicit modules in the prebuilt module paths (specified via `-fprebuilt-module-path`). To not modify existing behavior, this search takes place after the standard search for prebuilt modules. If not Here is a workflow illustrating how both the producer and consumer of prebuilt modules would need to know what versions of prebuilt modules are available and where they are located. clang -cc1 -x c modulemap -fmodules -emit-module -fmodule-name=foo -fmodules-cache-path=prebuilt_modules_v1 <config 1 options> clang -cc1 -x c modulemap -fmodules -emit-module -fmodule-name=foo -fmodules-cache-path=prebuilt_modules_v2 <config 2 options> clang -cc1 -x c modulemap -fmodules -emit-module -fmodule-name=foo -fmodules-cache-path=prebuilt_modules_v3 <config 3 options> clang -cc1 -x c use.c -fmodules fmodule-map-file=modulemap -fprebuilt-module-path=prebuilt_modules_v1 <config 1 options> clang -cc1 -x c use.c -fmodules fmodule-map-file=modulemap <non-prebuilt config options> With prebuilt implicit modules, the producer can generate prebuilt modules as usual, all in the same output directory. The same mechanisms as for implicit modules take care of incorporating hashes in the path to distinguish between module versions. Note that we do not specify the output module filename, so `-o` implicit modules are generated in the cache path `prebuilt_modules`. clang -cc1 -x c modulemap -fmodules -emit-module -fmodule-name=foo -fmodules-cache-path=prebuilt_modules <config 1 options> clang -cc1 -x c modulemap -fmodules -emit-module -fmodule-name=foo -fmodules-cache-path=prebuilt_modules <config 2 options> clang -cc1 -x c modulemap -fmodules -emit-module -fmodule-name=foo -fmodules-cache-path=prebuilt_modules <config 3 options> The user can now simply enable prebuilt implicit modules and point to the prebuilt modules cache. No need to "parse" command-line options to decide what prebuilt modules (paths) to use. clang -cc1 -x c use.c -fmodules fmodule-map-file=modulemap -fprebuilt-module-path=prebuilt_modules -fprebuilt-implicit-modules <config 1 options> clang -cc1 -x c use.c -fmodules fmodule-map-file=modulemap -fprebuilt-module-path=prebuilt_modules -fprebuilt-implicit-modules <non-prebuilt config options> This is for example particularly useful in a use-case where compilation is expensive, and the configurations expected to be used are predictable, but not controlled by the producer of prebuilt modules. Modules for the set of predictable configurations can be prebuilt, and using them does not require "parsing" the configuration (command-line options). Reviewed By: Bigcheese Differential Revision: https://reviews.llvm.org/D68997
1 parent f0e585d commit 71e108c

File tree

14 files changed

+251
-12
lines changed

14 files changed

+251
-12
lines changed

clang/docs/Modules.rst

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ Command-line parameters
225225
``-fprebuilt-module-path=<directory>``
226226
Specify the path to the prebuilt modules. If specified, we will look for modules in this directory for a given top-level module name. We don't need a module map for loading prebuilt modules in this directory and the compiler will not try to rebuild these modules. This can be specified multiple times.
227227

228+
``-fprebuilt-implicit-modules``
229+
Enable prebuilt implicit modules. If a prebuilt module is not found in the
230+
prebuilt modules paths (specified via ``-fprebuilt-module-path``), we will
231+
look for a matching implicit module in the prebuilt modules paths.
232+
228233
-cc1 Options
229234
~~~~~~~~~~~~
230235

@@ -235,6 +240,123 @@ Command-line parameters
235240
being built if the command line arguments are not homogeneous across your
236241
build.
237242

243+
Using Prebuilt Modules
244+
----------------------
245+
246+
Below are a few examples illustrating uses of prebuilt modules via the different options.
247+
248+
First, let's set up files for our examples.
249+
250+
.. code-block:: c
251+
252+
/* A.h */
253+
#ifdef ENABLE_A
254+
void a() {}
255+
#endif
256+
257+
.. code-block:: c
258+
259+
/* B.h */
260+
#include "A.h"
261+
262+
.. code-block:: c
263+
264+
/* use.c */
265+
#include "B.h"
266+
void use() {
267+
#ifdef ENABLE_A
268+
a();
269+
#endif
270+
}
271+
272+
.. code-block:: c
273+
274+
/* module.modulemap */
275+
module A {
276+
header "A.h"
277+
}
278+
module B {
279+
header "B.h"
280+
export *
281+
}
282+
283+
In the examples below, the compilation of ``use.c`` can be done without ``-cc1``, but the commands used to prebuild the modules would need to be updated to take into account the default options passed to ``clang -cc1``. (See ``clang use.c -v``)
284+
Note also that, since we use ``-cc1``, we specify the ``-fmodule-map-file=`` or ``-fimplicit-module-maps`` options explicitly. When using the clang driver, ``-fimplicit-module-maps`` is implied by ``-fmodules``.
285+
286+
First let us use an explicit mapping from modules to files.
287+
288+
.. code-block:: sh
289+
290+
rm -rf prebuilt ; mkdir prebuilt
291+
clang -cc1 -emit-module -o prebuilt/A.pcm -fmodules module.modulemap -fmodule-name=A
292+
clang -cc1 -emit-module -o prebuilt/B.pcm -fmodules module.modulemap -fmodule-name=B -fmodule-file=A=prebuilt/A.pcm
293+
clang -cc1 -emit-obj use.c -fmodules -fmodule-map-file=module.modulemap -fmodule-file=A=prebuilt/A.pcm -fmodule-file=B=prebuilt/B.pcm
294+
295+
Instead of of specifying the mappings manually, it can be convenient to use the ``-fprebuilt-module-path`` option. Let's also use ``-fimplicit-module-maps`` instead of manually pointing to our module map.
296+
297+
.. code-block:: sh
298+
299+
rm -rf prebuilt; mkdir prebuilt
300+
clang -cc1 -emit-module -o prebuilt/A.pcm -fmodules module.modulemap -fmodule-name=A
301+
clang -cc1 -emit-module -o prebuilt/B.pcm -fmodules module.modulemap -fmodule-name=B -fprebuilt-module-path=prebuilt
302+
clang -cc1 -emit-obj use.c -fmodules -fimplicit-module-maps -fprebuilt-module-path=prebuilt
303+
304+
A trick to prebuild all modules required for our source file in one command is to generate implicit modules while using the ``-fdisable-module-hash`` option.
305+
306+
.. code-block:: sh
307+
308+
rm -rf prebuilt ; mkdir prebuilt
309+
clang -cc1 -emit-obj use.c -fmodules -fimplicit-module-maps -fmodules-cache-path=prebuilt -fdisable-module-hash
310+
ls prebuilt/*.pcm
311+
# prebuilt/A.pcm prebuilt/B.pcm
312+
313+
Note that with explicit or prebuilt modules, we are responsible for, and should be particularly careful about the compatibility of our modules.
314+
Using mismatching compilation options and modules may lead to issues.
315+
316+
.. code-block:: sh
317+
318+
clang -cc1 -emit-obj use.c -fmodules -fimplicit-module-maps -fprebuilt-module-path=prebuilt -DENABLE_A
319+
# use.c:4:10: warning: implicit declaration of function 'a' is invalid in C99 [-Wimplicit-function-declaration]
320+
# return a(x);
321+
# ^
322+
# 1 warning generated.
323+
324+
So we need to maintain multiple versions of prebuilt modules. We can do so using a manual module mapping, or pointing to a different prebuilt module cache path. For example:
325+
326+
.. code-block:: sh
327+
328+
rm -rf prebuilt ; mkdir prebuilt ; rm -rf prebuilt_a ; mkdir prebuilt_a
329+
clang -cc1 -emit-obj use.c -fmodules -fimplicit-module-maps -fmodules-cache-path=prebuilt -fdisable-module-hash
330+
clang -cc1 -emit-obj use.c -fmodules -fimplicit-module-maps -fmodules-cache-path=prebuilt_a -fdisable-module-hash -DENABLE_A
331+
clang -cc1 -emit-obj use.c -fmodules -fimplicit-module-maps -fprebuilt-module-path=prebuilt
332+
clang -cc1 -emit-obj use.c -fmodules -fimplicit-module-maps -fprebuilt-module-path=prebuilt_a -DENABLE_A
333+
334+
335+
Instead of managing the different module versions manually, we can build implicit modules in a given cache path (using ``-fmodules-cache-path``), and reuse them as prebuilt implicit modules by passing ``-fprebuilt-module-path`` and ``-fprebuilt-implicit-modules``.
336+
337+
.. code-block:: sh
338+
339+
rm -rf prebuilt; mkdir prebuilt
340+
clang -cc1 -emit-obj -o use.o use.c -fmodules -fimplicit-module-maps -fmodules-cache-path=prebuilt
341+
clang -cc1 -emit-obj -o use.o use.c -fmodules -fimplicit-module-maps -fmodules-cache-path=prebuilt -DENABLE_A
342+
find prebuilt -name "*.pcm"
343+
# prebuilt/1AYBIGPM8R2GA/A-3L1K4LUA6O31.pcm
344+
# prebuilt/1AYBIGPM8R2GA/B-3L1K4LUA6O31.pcm
345+
# prebuilt/VH0YZMF1OIRK/A-3L1K4LUA6O31.pcm
346+
# prebuilt/VH0YZMF1OIRK/B-3L1K4LUA6O31.pcm
347+
clang -cc1 -emit-obj -o use.o use.c -fmodules -fimplicit-module-maps -fprebuilt-module-path=prebuilt -fprebuilt-implicit-modules
348+
clang -cc1 -emit-obj -o use.o use.c -fmodules -fimplicit-module-maps -fprebuilt-module-path=prebuilt -fprebuilt-implicit-modules -DENABLE_A
349+
350+
Finally we want to allow implicit modules for configurations that were not prebuilt. When using the clang driver a module cache path is implicitly selected. Using ``-cc1``, we simply add use the ``-fmodules-cache-path`` option.
351+
352+
.. code-block:: sh
353+
354+
clang -cc1 -emit-obj -o use.o use.c -fmodules -fimplicit-module-maps -fprebuilt-module-path=prebuilt -fprebuilt-implicit-modules -fmodules-cache-path=cache
355+
clang -cc1 -emit-obj -o use.o use.c -fmodules -fimplicit-module-maps -fprebuilt-module-path=prebuilt -fprebuilt-implicit-modules -fmodules-cache-path=cache -DENABLE_A
356+
clang -cc1 -emit-obj -o use.o use.c -fmodules -fimplicit-module-maps -fprebuilt-module-path=prebuilt -fprebuilt-implicit-modules -fmodules-cache-path=cache -DENABLE_A -DOTHER_OPTIONS
357+
358+
This way, a single directory containing multiple variants of modules can be prepared and reused. The options configuring the module cache are independent of other options.
359+
238360
Module Semantics
239361
================
240362

clang/include/clang/Driver/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,6 +1439,9 @@ def fmodules_user_build_path : Separate<["-"], "fmodules-user-build-path">, Grou
14391439
def fprebuilt_module_path : Joined<["-"], "fprebuilt-module-path=">, Group<i_Group>,
14401440
Flags<[NoXarchOption, CC1Option]>, MetaVarName<"<directory>">,
14411441
HelpText<"Specify the prebuilt module path">;
1442+
def fprebuilt_implicit_modules : Flag <["-"], "fprebuilt-implicit-modules">, Group<f_Group>,
1443+
Flags<[NoXarchOption, CC1Option]>,
1444+
HelpText<"Look up implicit modules in the prebuilt module path">;
14421445
def fmodules_prune_interval : Joined<["-"], "fmodules-prune-interval=">, Group<i_Group>,
14431446
Flags<[CC1Option]>, MetaVarName<"<seconds>">,
14441447
HelpText<"Specify the interval (in seconds) between attempts to prune the module cache">;

clang/include/clang/Frontend/CompilerInstance.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,10 @@ class CompilerInstance : public ModuleLoader {
649649
/// and replace any existing one with it.
650650
void createPreprocessor(TranslationUnitKind TUKind);
651651

652-
std::string getSpecificModuleCachePath();
652+
std::string getSpecificModuleCachePath(StringRef ModuleHash);
653+
std::string getSpecificModuleCachePath() {
654+
return getSpecificModuleCachePath(getInvocation().getModuleHash());
655+
}
653656

654657
/// Create the AST context.
655658
void createASTContext();

clang/include/clang/Lex/HeaderSearch.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@ class HeaderSearch {
183183
/// a system header.
184184
std::vector<std::pair<std::string, bool>> SystemHeaderPrefixes;
185185

186+
/// The hash used for module cache paths.
187+
std::string ModuleHash;
188+
186189
/// The path to the module cache.
187190
std::string ModuleCachePath;
188191

@@ -319,11 +322,17 @@ class HeaderSearch {
319322
return {};
320323
}
321324

325+
/// Set the hash to use for module cache paths.
326+
void setModuleHash(StringRef Hash) { ModuleHash = std::string(Hash); }
327+
322328
/// Set the path to the module cache.
323329
void setModuleCachePath(StringRef CachePath) {
324330
ModuleCachePath = std::string(CachePath);
325331
}
326332

333+
/// Retrieve the module hash.
334+
StringRef getModuleHash() const { return ModuleHash; }
335+
327336
/// Retrieve the path to the module cache.
328337
StringRef getModuleCachePath() const { return ModuleCachePath; }
329338

@@ -512,6 +521,15 @@ class HeaderSearch {
512521
std::string getPrebuiltModuleFileName(StringRef ModuleName,
513522
bool FileMapOnly = false);
514523

524+
/// Retrieve the name of the prebuilt module file that should be used
525+
/// to load the given module.
526+
///
527+
/// \param Module The module whose module file name will be returned.
528+
///
529+
/// \returns The name of the module file that corresponds to this module,
530+
/// or an empty string if this module does not correspond to any module file.
531+
std::string getPrebuiltImplicitModuleFileName(Module *Module);
532+
515533
/// Retrieve the name of the (to-be-)cached module file that should
516534
/// be used to load a module with the given name.
517535
///
@@ -614,6 +632,22 @@ class HeaderSearch {
614632
Module *lookupModule(StringRef ModuleName, StringRef SearchName,
615633
bool AllowExtraModuleMapSearch = false);
616634

635+
/// Retrieve the name of the (to-be-)cached module file that should
636+
/// be used to load a module with the given name.
637+
///
638+
/// \param ModuleName The module whose module file name will be returned.
639+
///
640+
/// \param ModuleMapPath A path that when combined with \c ModuleName
641+
/// uniquely identifies this module. See Module::ModuleMap.
642+
///
643+
/// \param CachePath A path to the module cache.
644+
///
645+
/// \returns The name of the module file that corresponds to this module,
646+
/// or an empty string if this module does not correspond to any module file.
647+
std::string getCachedModuleFileNameImpl(StringRef ModuleName,
648+
StringRef ModuleMapPath,
649+
StringRef CachePath);
650+
617651
/// Retrieve a module with the given name, which may be part of the
618652
/// given framework.
619653
///

clang/include/clang/Lex/HeaderSearchOptions.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ class HeaderSearchOptions {
142142
/// file.
143143
unsigned ModuleMapFileHomeIsCwd : 1;
144144

145+
/// Also search for prebuilt implicit modules in the prebuilt module cache
146+
/// path.
147+
unsigned EnablePrebuiltImplicitModules : 1;
148+
145149
/// The interval (in seconds) between pruning operations.
146150
///
147151
/// This operation is expensive, because it requires Clang to walk through
@@ -217,8 +221,9 @@ class HeaderSearchOptions {
217221
HeaderSearchOptions(StringRef _Sysroot = "/")
218222
: Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(false),
219223
ImplicitModuleMaps(false), ModuleMapFileHomeIsCwd(false),
220-
UseBuiltinIncludes(true), UseStandardSystemIncludes(true),
221-
UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false),
224+
EnablePrebuiltImplicitModules(false), UseBuiltinIncludes(true),
225+
UseStandardSystemIncludes(true), UseStandardCXXIncludes(true),
226+
UseLibcxx(false), Verbose(false),
222227
ModulesValidateOncePerBuildSession(false),
223228
ModulesValidateSystemHeaders(false),
224229
ValidateASTInputFilesContent(false), UseDebugInfo(false),

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3379,6 +3379,8 @@ static void RenderModulesOptions(Compilation &C, const Driver &D,
33793379
std::string("-fprebuilt-module-path=") + A->getValue()));
33803380
A->claim();
33813381
}
3382+
if (Args.hasFlag(options::OPT_fprebuilt_implicit_modules, false))
3383+
CmdArgs.push_back("-fprebuilt-implicit-modules");
33823384
if (Args.hasFlag(options::OPT_fmodules_validate_input_files_content,
33833385
options::OPT_fno_modules_validate_input_files_content,
33843386
false))

clang/lib/Frontend/CompilerInstance.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -428,8 +428,12 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
428428

429429
PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP);
430430

431-
if (PP->getLangOpts().Modules && PP->getLangOpts().ImplicitModules)
432-
PP->getHeaderSearchInfo().setModuleCachePath(getSpecificModuleCachePath());
431+
if (PP->getLangOpts().Modules && PP->getLangOpts().ImplicitModules) {
432+
std::string ModuleHash = getInvocation().getModuleHash();
433+
PP->getHeaderSearchInfo().setModuleHash(ModuleHash);
434+
PP->getHeaderSearchInfo().setModuleCachePath(
435+
getSpecificModuleCachePath(ModuleHash));
436+
}
433437

434438
// Handle generating dependencies, if requested.
435439
const DependencyOutputOptions &DepOpts = getDependencyOutputOpts();
@@ -477,13 +481,11 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
477481
}
478482
}
479483

480-
std::string CompilerInstance::getSpecificModuleCachePath() {
481-
// Set up the module path, including the hash for the
482-
// module-creation options.
484+
std::string CompilerInstance::getSpecificModuleCachePath(StringRef ModuleHash) {
485+
// Set up the module path, including the hash for the module-creation options.
483486
SmallString<256> SpecificModuleCache(getHeaderSearchOpts().ModuleCachePath);
484487
if (!SpecificModuleCache.empty() && !getHeaderSearchOpts().DisableModuleHash)
485-
llvm::sys::path::append(SpecificModuleCache,
486-
getInvocation().getModuleHash());
488+
llvm::sys::path::append(SpecificModuleCache, ModuleHash);
487489
return std::string(SpecificModuleCache.str());
488490
}
489491

@@ -1673,6 +1675,8 @@ static ModuleSource selectModuleSource(
16731675
if (!HSOpts.PrebuiltModuleFiles.empty() ||
16741676
!HSOpts.PrebuiltModulePaths.empty()) {
16751677
ModuleFilename = HS.getPrebuiltModuleFileName(ModuleName);
1678+
if (HSOpts.EnablePrebuiltImplicitModules && ModuleFilename.empty())
1679+
ModuleFilename = HS.getPrebuiltImplicitModuleFileName(M);
16761680
if (!ModuleFilename.empty())
16771681
return MS_PrebuiltModulePath;
16781682
}

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2191,6 +2191,8 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
21912191
!Args.hasArg(OPT_fmodules_disable_diagnostic_validation);
21922192
Opts.ImplicitModuleMaps = Args.hasArg(OPT_fimplicit_module_maps);
21932193
Opts.ModuleMapFileHomeIsCwd = Args.hasArg(OPT_fmodule_map_file_home_is_cwd);
2194+
Opts.EnablePrebuiltImplicitModules =
2195+
Args.hasArg(OPT_fprebuilt_implicit_modules);
21942196
Opts.ModuleCachePruneInterval =
21952197
getLastArgIntValue(Args, OPT_fmodules_prune_interval, 7 * 24 * 60 * 60);
21962198
Opts.ModuleCachePruneAfter =

clang/lib/Lex/HeaderSearch.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,39 @@ std::string HeaderSearch::getPrebuiltModuleFileName(StringRef ModuleName,
164164
return {};
165165
}
166166

167+
std::string HeaderSearch::getPrebuiltImplicitModuleFileName(Module *Module) {
168+
const FileEntry *ModuleMap =
169+
getModuleMap().getModuleMapFileForUniquing(Module);
170+
StringRef ModuleName = Module->Name;
171+
StringRef ModuleMapPath = ModuleMap->getName();
172+
StringRef ModuleCacheHash = HSOpts->DisableModuleHash ? "" : getModuleHash();
173+
for (const std::string &Dir : HSOpts->PrebuiltModulePaths) {
174+
SmallString<256> CachePath(Dir);
175+
llvm::sys::fs::make_absolute(CachePath);
176+
llvm::sys::path::append(CachePath, ModuleCacheHash);
177+
std::string FileName =
178+
getCachedModuleFileNameImpl(ModuleName, ModuleMapPath, CachePath);
179+
if (!FileName.empty() && getFileMgr().getFile(FileName))
180+
return FileName;
181+
}
182+
return {};
183+
}
184+
167185
std::string HeaderSearch::getCachedModuleFileName(StringRef ModuleName,
168186
StringRef ModuleMapPath) {
187+
return getCachedModuleFileNameImpl(ModuleName, ModuleMapPath,
188+
getModuleCachePath());
189+
}
190+
191+
std::string HeaderSearch::getCachedModuleFileNameImpl(StringRef ModuleName,
192+
StringRef ModuleMapPath,
193+
StringRef CachePath) {
169194
// If we don't have a module cache path or aren't supposed to use one, we
170195
// can't do anything.
171-
if (getModuleCachePath().empty())
196+
if (CachePath.empty())
172197
return {};
173198

174-
SmallString<256> Result(getModuleCachePath());
199+
SmallString<256> Result(CachePath);
175200
llvm::sys::fs::make_absolute(Result);
176201

177202
if (HSOpts->DisableModuleHash) {

clang/lib/Serialization/ASTReader.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5844,6 +5844,7 @@ bool ASTReader::ParseHeaderSearchOptions(const RecordData &Record,
58445844
HSOpts.DisableModuleHash = Record[Idx++];
58455845
HSOpts.ImplicitModuleMaps = Record[Idx++];
58465846
HSOpts.ModuleMapFileHomeIsCwd = Record[Idx++];
5847+
HSOpts.EnablePrebuiltImplicitModules = Record[Idx++];
58475848
HSOpts.UseBuiltinIncludes = Record[Idx++];
58485849
HSOpts.UseStandardSystemIncludes = Record[Idx++];
58495850
HSOpts.UseStandardCXXIncludes = Record[Idx++];

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,6 +1320,7 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
13201320
Record.push_back(HSOpts.DisableModuleHash);
13211321
Record.push_back(HSOpts.ImplicitModuleMaps);
13221322
Record.push_back(HSOpts.ModuleMapFileHomeIsCwd);
1323+
Record.push_back(HSOpts.EnablePrebuiltImplicitModules);
13231324
Record.push_back(HSOpts.UseBuiltinIncludes);
13241325
Record.push_back(HSOpts.UseStandardSystemIncludes);
13251326
Record.push_back(HSOpts.UseStandardCXXIncludes);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
const int a = 1;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module module_a { header "a.h" }

0 commit comments

Comments
 (0)