Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -2285,6 +2285,9 @@ PosFlag, NegFlag, BothFlags<[NoXarchOption, CC1Option]>>; +def fsave_std_cxx_module_file : Flag<["-"], "fsave-std-c++-module-file">, Flags<[NoXarchOption, CC1Option]>, + HelpText<"Save intermediate module file results when compiling a standard C++ module unit.">; + def fmodules_prune_interval : Joined<["-"], "fmodules-prune-interval=">, Group, Flags<[CC1Option]>, MetaVarName<"">, HelpText<"Specify the interval (in seconds) between attempts to prune the module cache">, Index: clang/lib/Driver/Driver.cpp =================================================================== --- clang/lib/Driver/Driver.cpp +++ clang/lib/Driver/Driver.cpp @@ -5552,6 +5552,25 @@ return "-"; } + // If `-fsave-std-c++-module-file` is specfied, then: + // - If `-o` is specified, the module file is writing to the same path + // with the output file in module file's suffix. + // - If `-o` is not specified, the module file is writing to the same path + // with the input file in module file's suffix. + if (!AtTopLevel && isa(JA) && + JA.getType() == types::TY_ModuleFile && + C.getArgs().hasArg(options::OPT_fsave_std_cxx_module_file)) { + SmallString<128> TempPath; + if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o)) + TempPath = FinalOutput->getValue(); + else + TempPath = BaseInput; + + const char *Extension = types::getTypeTempSuffix(JA.getType()); + llvm::sys::path::replace_extension(TempPath, Extension); + return C.addResultFile(C.getArgs().MakeArgString(TempPath.c_str()), &JA); + } + if (IsDXCMode() && !C.getArgs().hasArg(options::OPT_o)) return "-"; Index: clang/test/Driver/save-std-c++-module-file.cpp =================================================================== --- /dev/null +++ clang/test/Driver/save-std-c++-module-file.cpp @@ -0,0 +1,15 @@ +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: split-file %s %t +// +// RUN: %clang -std=c++20 %t/Hello.cppm -fsave-std-c++-module-file -### 2>&1 | \ +// RUN: FileCheck %t/Hello.cppm -DPREFIX=%t +// +// RUN: %clang -std=c++20 %t/Hello.cppm -fsave-std-c++-module-file -o %t/output/Hello.o \ +// RUN: -### 2>&1 | FileCheck %t/Hello.cppm -DPREFIX=%t --check-prefix=CHECK-WITH-OUTPUT + +//--- Hello.cppm +export module Hello; + +// CHECK: "-o" "[[PREFIX]]/Hello.pcm" +// CHECK-WITH-OUTPUT: "-o" "[[PREFIX]]/output/Hello.pcm"