diff options
author | Chuanqi Xu <yedeng.yd@linux.alibaba.com> | 2022-12-28 13:48:08 +0800 |
---|---|---|
committer | Chuanqi Xu <yedeng.yd@linux.alibaba.com> | 2023-01-16 11:05:33 +0800 |
commit | f89327e28bc17a1d80fd5523520e62d8dd53c1cb (patch) | |
tree | 4e287ec43600e4215780403f2a7b0f82171f8e48 /clang/lib/Driver/Driver.cpp | |
parent | 396ad408fdf7a34581a9df5bd22e5913baf26f35 (diff) | |
download | llvm-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.cpp | 38 |
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 { |