aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Driver/Driver.cpp
diff options
context:
space:
mode:
authorChuanqi Xu <yedeng.yd@linux.alibaba.com>2022-12-28 13:48:08 +0800
committerChuanqi Xu <yedeng.yd@linux.alibaba.com>2023-01-16 11:05:33 +0800
commitf89327e28bc17a1d80fd5523520e62d8dd53c1cb (patch)
tree4e287ec43600e4215780403f2a7b0f82171f8e48 /clang/lib/Driver/Driver.cpp
parent396ad408fdf7a34581a9df5bd22e5913baf26f35 (diff)
downloadllvm-f89327e28bc17a1d80fd5523520e62d8dd53c1cb.zip
llvm-f89327e28bc17a1d80fd5523520e62d8dd53c1cb.tar.gz
llvm-f89327e28bc17a1d80fd5523520e62d8dd53c1cb.tar.bz2
[Driver] [Modules] Support -fmodule-output (1/2)
Patches to support the one-phase compilation model for modules. The behavior: (1) If -o and -c 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) Otherwise, the module file is in the same path within the working directory directory with the name of the input file with a new suffix .pcm For example, ``` Hello.cppm Use.cpp ``` A trivial one and the contents are ignored. When we run: ``` clang++ -std=c++20 -fmodule-output Hello.cppm -c ``` The directory would look like: ``` Hello.cppm Hello.o Hello.pcm Use.cpp ``` And if we run: ``` clang++ -std=c++20 -fmodule-output Hello.cppm -c -o output/Hello.o ``` Then the `output` directory may look like: ``` Hello.o Hello.pcm ``` Reviewed By: dblaikie, iains, tahonermann Differential Revision: https://reviews.llvm.org/D137058
Diffstat (limited to 'clang/lib/Driver/Driver.cpp')
-rw-r--r--clang/lib/Driver/Driver.cpp38
1 files changed, 36 insertions, 2 deletions
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index fe9e9bb..bc70a92 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -5553,6 +5553,30 @@ const char *Driver::CreateTempFile(Compilation &C, StringRef Prefix,
return C.addTempFile(C.getArgs().MakeArgString(TmpName));
}
+// Calculate the output path of the module file when compiling a module unit
+// with the `-fmodule-output` option specified. The behavior is:
+// - If the output object file of the module unit is specified, the output path
+// of the module file should be the same with the output object file except
+// the corresponding suffix. This requires both `-o` and `-c` are specified.
+// - Otherwise, the output path of the module file will be the same with the
+// input with the corresponding suffix.
+static const char *GetModuleOutputPath(Compilation &C, const JobAction &JA,
+ const char *BaseInput) {
+ assert(isa<PrecompileJobAction>(JA) && JA.getType() == types::TY_ModuleFile &&
+ C.getArgs().hasArg(options::OPT_fmodule_output));
+
+ SmallString<64> OutputPath;
+ Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o);
+ if (FinalOutput && C.getArgs().hasArg(options::OPT_c))
+ OutputPath = FinalOutput->getValue();
+ else
+ OutputPath = BaseInput;
+
+ const char *Extension = types::getTypeTempSuffix(JA.getType());
+ llvm::sys::path::replace_extension(OutputPath, Extension);
+ return C.addResultFile(C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
+}
+
const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA,
const char *BaseInput,
StringRef OrigBoundArch, bool AtTopLevel,
@@ -5609,6 +5633,16 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA,
&JA);
}
+ if (MultipleArchs && C.getArgs().hasArg(options::OPT_fmodule_output))
+ Diag(clang::diag::err_drv_module_output_with_multiple_arch);
+
+ // If we're emitting a module output with the specified option
+ // `-fmodule-output`.
+ if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
+ JA.getType() == types::TY_ModuleFile &&
+ C.getArgs().hasArg(options::OPT_fmodule_output))
+ return GetModuleOutputPath(C, JA, BaseInput);
+
// Output to a temporary file?
if ((!AtTopLevel && !isSaveTempsEnabled() &&
!C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
@@ -5771,9 +5805,9 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA,
else
llvm::sys::path::append(BasePath, NamedOutput);
return C.addResultFile(C.getArgs().MakeArgString(BasePath.c_str()), &JA);
- } else {
- return C.addResultFile(NamedOutput, &JA);
}
+
+ return C.addResultFile(NamedOutput, &JA);
}
std::string Driver::GetFilePath(StringRef Name, const ToolChain &TC) const {