ChuanqiXu updated this revision to Diff 483443.
ChuanqiXu added a comment.

- when `-fmodule-output` and `-o` are both specified, generate the module file 
into the directory of the output file and name the module file with the name of 
the input file with module file's suffixes. (Previously, the name of the module 
will be the same with the output file). The change tries to avoid rewrite the 
module file when we specify multiple input files in one command line.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137058/new/

https://reviews.llvm.org/D137058

Files:
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/Driver.cpp
  clang/test/Driver/lit.local.cfg
  clang/test/Driver/module-output.cppm

Index: clang/test/Driver/module-output.cppm
===================================================================
--- /dev/null
+++ clang/test/Driver/module-output.cppm
@@ -0,0 +1,26 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: split-file %s %t
+//
+// Tests that the .pcm file will be generated in the same direcotry with the specified
+// output and the name of the .pcm file should be the same with the input file.
+// RUN: %clang -std=c++20 %t/Hello.cppm -fmodule-output -c -o %t/output/Hello.o \
+// RUN:   -### 2>&1 | FileCheck %t/Hello.cppm
+//
+// Tests that the output file will be generated in the output directory when we
+// specified multiple input files.
+// RUN: %clang -std=c++20 %t/Hello.cppm %t/AnotherModule.cppm -fmodule-output -o \
+// RUN:   %t/output/a.out -### 2>&1 | FileCheck  %t/AnotherModule.cppm
+
+//--- Hello.cppm
+export module Hello;
+
+// CHECK: "-emit-module-interface" {{.*}}"-main-file-name" "Hello.cppm" {{.*}}"-o" "{{.*}}/output/Hello.pcm" "-x" "c++" "{{.*}}/Hello.cppm"
+// CHECK: "-emit-obj" {{.*}}"-main-file-name" "Hello.cppm" {{.*}}"-o" "{{.*}}/output/Hello.o" "-x" "pcm" "{{.*}}/output/Hello.pcm"
+
+//--- AnotherModule.cppm
+export module AnotherModule;
+// CHECK: "-emit-module-interface" {{.*}}"-main-file-name" "Hello.cppm" {{.*}}"-o" "{{.*}}/output/Hello.pcm" "-x" "c++" "{{.*}}/Hello.cppm"
+// CHECK: "-emit-obj" {{.*}}"-main-file-name" "Hello.cppm" {{.*}}"-o" "{{.*}}/Hello-{{.*}}.o" "-x" "pcm" "{{.*}}/output/Hello.pcm"
+// CHECK: "-emit-module-interface" {{.*}}"-main-file-name" "AnotherModule.cppm" {{.*}}"-o" "{{.*}}/output/AnotherModule.pcm" "-x" "c++" "{{.*}}/AnotherModule.cppm"
+// CHECK: "-emit-obj" {{.*}}"-main-file-name" "AnotherModule.cppm" {{.*}}"-o" "{{.*}}/AnotherModule-{{.*}}.o" "-x" "pcm" "{{.*}}/output/AnotherModule.pcm"
Index: clang/test/Driver/lit.local.cfg
===================================================================
--- clang/test/Driver/lit.local.cfg
+++ clang/test/Driver/lit.local.cfg
@@ -1,6 +1,6 @@
 from lit.llvm import llvm_config
 
-config.suffixes = ['.c', '.cpp', '.h', '.m', '.mm', '.S', '.s', '.f90', '.F90', '.f95',
+config.suffixes = ['.c', '.cpp', '.cppm', '.h', '.m', '.mm', '.S', '.s', '.f90', '.F90', '.f95',
                    '.cu', '.rs', '.cl', '.clcpp', '.hip', '.hlsl']
 config.substitutions = list(config.substitutions)
 config.substitutions.insert(0,
Index: clang/lib/Driver/Driver.cpp
===================================================================
--- clang/lib/Driver/Driver.cpp
+++ clang/lib/Driver/Driver.cpp
@@ -5556,8 +5556,14 @@
   }
 
   // Output to a temporary file?
-  if ((!AtTopLevel && !isSaveTempsEnabled() &&
-       !C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
+  if ((!AtTopLevel &&
+       !isSaveTempsEnabled() &&
+         !C.getArgs().hasArg(options::OPT__SLASH_Fo) &&
+       // We don't generate module file to temporary file if
+       // we specified `-fmodule-output`
+       (!isa<PrecompileJobAction>(JA) ||
+        JA.getType() != types::TY_ModuleFile ||
+        !C.getArgs().hasArg(options::OPT_fmodule_output))) ||
       CCGenDiagnostics) {
     StringRef Name = llvm::sys::path::filename(BaseInput);
     std::pair<StringRef, StringRef> Split = Name.split('.');
@@ -5714,9 +5720,27 @@
     else
       llvm::sys::path::append(BasePath, NamedOutput);
     return C.addResultFile(C.getArgs().MakeArgString(BasePath.c_str()), &JA);
-  } else {
-    return C.addResultFile(NamedOutput, &JA);
   }
+
+  // When we specified `-fmodule-output` and `-o`, the module file
+  // will be generated into the same directory with the output file
+  // and the name of the module file would be the input file with the
+  // new suffix '.pcm'.
+  if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
+      JA.getType() == types::TY_ModuleFile &&
+      C.getArgs().hasArg(options::OPT_fmodule_output) &&
+      C.getArgs().hasArg(options::OPT_o)) {
+    SmallString<128> OutputPath;
+    OutputPath = C.getArgs().getLastArg(options::OPT_o)->getValue();
+    llvm::sys::path::remove_filename(OutputPath);
+    if (OutputPath.empty())
+      OutputPath = NamedOutput;
+    else
+      llvm::sys::path::append(OutputPath, NamedOutput);
+    return C.addResultFile(C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
+  }
+  
+  return C.addResultFile(NamedOutput, &JA);
 }
 
 std::string Driver::GetFilePath(StringRef Name, const ToolChain &TC) const {
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -2285,6 +2285,9 @@
   PosFlag<SetTrue, [], "Look up implicit modules in the prebuilt module path">,
   NegFlag<SetFalse>, BothFlags<[NoXarchOption, CC1Option]>>;
 
+def fmodule_output : Flag<["-"], "fmodule-output">, 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

Reply via email to