Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -352,6 +352,11 @@
timestamp to be used in replacement of the current date and time in
the ``__DATE__``, ``__TIME__``, and ``__TIMESTAMP__`` macros. See
``_.
+- Now the clang will generate the BMI implicitly when we compile a module unit
+ directly. See
+ `How to produce a BMI
+ `_
+ for details.
New Compiler Flags
------------------
Index: clang/include/clang/Basic/DiagnosticCommonKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -349,6 +349,8 @@
// Modules
def err_module_format_unhandled : Error<
"no handler registered for module format '%0'">, DefaultFatal;
+def err_creating_default_module_cache_path : Error<
+ "unable to create default module cache path \"%0\": %1">;
// TransformActions
// TODO: Use a custom category name to distinguish rewriter errors.
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -2265,6 +2265,12 @@
def fmodules_cache_path : Joined<["-"], "fmodules-cache-path=">, Group,
Flags<[NoXarchOption, CC1Option]>, MetaVarName<"">,
HelpText<"Specify the module cache path">;
+def fcxx_modules_cache_path : Joined<["-"], "fc++-modules-cache-path=">, Group,
+ Flags<[NoXarchOption, CC1Option]>, MetaVarName<"">,
+ HelpText<"Specify the module cache path for standard c++ modules">;
+def fmodule_bmi_output : Joined<["-"], "fmodule-bmi-output=">, Group,
+ Flags<[NoXarchOption, CC1Option]>,
+ HelpText<"Specify the destination of built module interaface in one phase compilation model">;
def fmodules_user_build_path : Separate<["-"], "fmodules-user-build-path">, Group,
Flags<[NoXarchOption, CC1Option]>, MetaVarName<"">,
HelpText<"Specify the module user build path">,
Index: clang/lib/Driver/Driver.cpp
===================================================================
--- clang/lib/Driver/Driver.cpp
+++ clang/lib/Driver/Driver.cpp
@@ -5558,6 +5558,30 @@
return "-";
}
+ if (isa(JA) && JA.getType() == types::TY_ModuleFile) {
+ if (Arg *A = C.getArgs().getLastArg(options::OPT_fmodule_bmi_output))
+ return C.addResultFile(A->getValue(), &JA);
+
+ SmallString<128> Path;
+ if (Arg *A = C.getArgs().getLastArg(options::OPT_fcxx_modules_cache_path))
+ Path = A->getValue();
+ else
+ Driver::getDefaultModuleCachePath(Path);
+
+ std::error_code EC =
+ llvm::sys::fs::create_directories(Path, /*IgnoreExisting =*/true);
+ if (EC)
+ Diag(clang::diag::err_creating_default_module_cache_path)
+ << Path << EC.message();
+
+ StringRef Name = llvm::sys::path::filename(BaseInput);
+ llvm::sys::path::append(Path, Name.rsplit('.').first);
+ Path += ".";
+ Path += types::getTypeTempSuffix(JA.getType(), IsCLMode());
+
+ return C.addResultFile(C.getArgs().MakeArgString(Path.c_str()), &JA);
+ }
+
if (IsDXCMode() && !C.getArgs().hasArg(options::OPT_o))
return "-";
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -3750,6 +3750,7 @@
std::string("-fprebuilt-module-path=") + A->getValue()));
A->claim();
}
+
if (Args.hasFlag(options::OPT_fprebuilt_implicit_modules,
options::OPT_fno_prebuilt_implicit_modules, false))
CmdArgs.push_back("-fprebuilt-implicit-modules");
@@ -3759,6 +3760,18 @@
CmdArgs.push_back("-fvalidate-ast-input-files-content");
}
+ // If we're in standard c++ modules, lookup in cache path automatically.
+ if (HaveStdCXXModules) {
+ SmallString<128> Path;
+ if (Arg *A = Args.getLastArg(options::OPT_fcxx_modules_cache_path))
+ Path = A->getValue();
+ else
+ Driver::getDefaultModuleCachePath(Path);
+ if (!Path.empty())
+ CmdArgs.push_back(Args.MakeArgString(
+ std::string("-fprebuilt-module-path=") + Path));
+ }
+
// -fmodule-name specifies the module that is currently being built (or
// used for header checking by -fmodule-maps).
Args.AddLastArg(CmdArgs, options::OPT_fmodule_name_EQ);
Index: clang/test/Driver/create_module_cache.cpp
===================================================================
--- /dev/null
+++ clang/test/Driver/create_module_cache.cpp
@@ -0,0 +1,31 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: split-file %s %t
+//
+// RUN: not %clang -std=c++20 %t/M.cppm -fc++-modules-cache-path= -c -o %t/M.tmp.o 2>&1 | FileCheck %t/M.cppm --check-prefix=ERROR
+// RUN: %clang -std=c++20 %t/M.cppm -fc++-modules-cache-path=%t/abc -c -o -
+// RUN: ls %t | FileCheck %t/M.cppm --check-prefix=CHECK-AVAILABLE
+// RUN: %clang -std=c++20 %t/M.cppm -fc++-modules-cache-path=%t/abc -fno-implicit-modules -c -o -
+// RUN: ls %t | FileCheck %t/M.cppm --check-prefix=CHECK-AVAILABLE
+//
+// RUN: %clang -std=c++20 %t/Use.cpp -fc++-modules-cache-path=abc -### 2>&1 | FileCheck %t/Use.cpp
+// RUN: %clang -std=c++20 %t/Use.cpp -fc++-modules-cache-path=abc -fno-implicit-modules -### 2>&1 | FileCheck %t/Use.cpp
+//
+// Check that the compiler will generate M-Part.pcm correctly.
+// RUN: %clang -std=c++20 %t/Part.cppm -fmodule-bmi-output=%t/M-Part.pcm -c -o -
+// RUN: ls %t | FileCheck %t/Part.cppm --check-prefix=CHECK-AVAILABLE
+
+//--- M.cppm
+export module M;
+
+// ERROR: unable to create default module cache path "": No such file or directory
+// CHECK-AVAILABLE: abc
+
+//--- Use.cpp
+import M;
+
+// CHECK: -fprebuilt-module-path=abc
+
+//--- Part.cppm
+export module M:Part;
+// CHECK-AVAILABLE: M-Part.pcm
Index: clang/test/Modules/one-phase-compilation-named-modules.cppm
===================================================================
--- /dev/null
+++ clang/test/Modules/one-phase-compilation-named-modules.cppm
@@ -0,0 +1,26 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: split-file %s %t
+//
+// RUN: %clang -std=c++20 %t/M.cppm -c -o - -fc++-modules-cache-path=%t/pcm.cache
+// RUN: %clang -std=c++20 %t/Use.cpp -fsyntax-only -fprebuilt-module-path=%t/pcm.cache -Xclang -verify
+//
+// RUN: rm -f %t/M.pcm
+//
+// RUN: %clang -std=c++20 %t/MismatchedName.cppm -c -o - -fmodule-bmi-output=%t/pcm.cache/M.pcm
+// RUN: %clang -std=c++20 %t/Use.cpp -fsyntax-only -fprebuilt-module-path=%t/pcm.cache -Xclang -verify
+
+//--- M.cppm
+export module M;
+export int getValue();
+
+//--- MismatchedName.cppm
+export module M;
+export int getValue();
+
+//--- Use.cpp
+// expected-no-diagnostics
+import M;
+int Use() {
+ return getValue();
+}