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(); +}