ChuanqiXu created this revision. ChuanqiXu added reviewers: dblaikie, ben.boeckel, iains, tschuett. ChuanqiXu added a project: clang-modules. Herald added a project: All. ChuanqiXu requested review of this revision. Herald added subscribers: cfe-commits, MaskRay. Herald added a project: clang.
Patches to support the `one-phase` compilation model for modules. This is the successor of D134267 <https://reviews.llvm.org/D134267>. @dblaikie suggests to do the following 3 steps to make the `one-phase` compilation model. (1) Support `.cppm -> .pcm + .o` in one phase. (This patch) (2) Support specify the path of `.pcm` file in the one phase compilation. (3) Support the module cache. Then @ben.boeckel clarifies that the module cache is not necessary. So I won't pursue it too. This patch adds an option `-fsave-std-c++-module-file` to save the module file if we compile the module unit to object files directly. Why a new option? Because I think it may pollutes the space if we make the behavior default. And I feel good to add an option for this behavior. The behavior: (1) If `-o` is specified , the module file is in the same path within the same directory as the output the `-o` specified and with a new suffix `.pcm`. (2) If `-o` is not specified, the module file is in the same path within the same directory as the input file and with the new suffix `.pcm`. For example, Hello.cppm Use.cpp A trivial one and the contents are ignored. When we run: clang++ -std=c++20 -fsave-std-c++-module-file Hello.cppm -c The directory would look like: Hello.cppm Hello.o Hello.pcm Use.cpp And if we run: clang++ -std=c++20 -fsave-std-c++-module-file Hello.cppm -c -o output/Hello.o Then the `output` directory may look like: Hello.o Hello.pcm Can we compile the `Hello World` example in one command line? Yes! we can do the following one: clang++ -std=c++20 Hello.cppm Use.cpp -fsave-std-c++-module-file -fprebuilt-module-path=. --- I'll add the ReleaseNotes and documentation after the series got accepted. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D137058 Files: clang/include/clang/Driver/Options.td clang/lib/Driver/Driver.cpp clang/test/Driver/save-std-c++-module-file.cpp Index: clang/test/Driver/save-std-c++-module-file.cpp =================================================================== --- /dev/null +++ clang/test/Driver/save-std-c++-module-file.cpp @@ -0,0 +1,17 @@ +// 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 -c +// RUN: ls %t | FileCheck %t/Hello.cppm --check-prefix=CHECK-DEFAULT +// +// RUN: mkdir %t/tmp +// RUN: %clang -std=c++20 %t/Hello.cppm -fsave-std-c++-module-file -c -o %t/tmp/H.o +// RUN: ls %t/tmp | FileCheck %t/Hello.cppm --check-prefix=CHECK-O + + +//--- Hello.cppm +export module Hello; + +// CHECK-DEFAULT: Hello.pcm +// CHECK-O: H.pcm Index: clang/lib/Driver/Driver.cpp =================================================================== --- clang/lib/Driver/Driver.cpp +++ clang/lib/Driver/Driver.cpp @@ -5532,6 +5532,28 @@ 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. + // + // FIXME: Do we need to handle the case that the calculated output is + // conflicting with the specified output file or the input file? + if (!AtTopLevel && isa<PrecompileJobAction>(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/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -2276,6 +2276,9 @@ PosFlag<SetTrue, [], "Look up implicit modules in the prebuilt module path">, NegFlag<SetFalse>, 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<i_Group>, Flags<[CC1Option]>, MetaVarName<"<seconds>">, HelpText<"Specify the interval (in seconds) between attempts to prune the module cache">,
Index: clang/test/Driver/save-std-c++-module-file.cpp =================================================================== --- /dev/null +++ clang/test/Driver/save-std-c++-module-file.cpp @@ -0,0 +1,17 @@ +// 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 -c +// RUN: ls %t | FileCheck %t/Hello.cppm --check-prefix=CHECK-DEFAULT +// +// RUN: mkdir %t/tmp +// RUN: %clang -std=c++20 %t/Hello.cppm -fsave-std-c++-module-file -c -o %t/tmp/H.o +// RUN: ls %t/tmp | FileCheck %t/Hello.cppm --check-prefix=CHECK-O + + +//--- Hello.cppm +export module Hello; + +// CHECK-DEFAULT: Hello.pcm +// CHECK-O: H.pcm Index: clang/lib/Driver/Driver.cpp =================================================================== --- clang/lib/Driver/Driver.cpp +++ clang/lib/Driver/Driver.cpp @@ -5532,6 +5532,28 @@ 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. + // + // FIXME: Do we need to handle the case that the calculated output is + // conflicting with the specified output file or the input file? + if (!AtTopLevel && isa<PrecompileJobAction>(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/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -2276,6 +2276,9 @@ PosFlag<SetTrue, [], "Look up implicit modules in the prebuilt module path">, NegFlag<SetFalse>, 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<i_Group>, Flags<[CC1Option]>, MetaVarName<"<seconds>">, HelpText<"Specify the interval (in seconds) between attempts to prune the module cache">,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits