diff options
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 { |