forked from OSchip/llvm-project
PR 17421: Implemented -save-temps={obj|cwd} option
-save-temps=cwd is equivalent to -save-temps -save-temps=obj saves temporary file in the same directory as output This helps to avoid clobbering of temp files in case of parallel compilation with -save-temps of the files that have the same name but located in different directories. Patch by Artem Belevich Reviewed By: rnk Differential Revision: http://reviews.llvm.org/D7304 llvm-svn: 227886
This commit is contained in:
parent
d5c235dab8
commit
68eb60b8c4
|
@ -61,6 +61,12 @@ class Driver {
|
|||
CLMode
|
||||
} Mode;
|
||||
|
||||
enum SaveTempsMode {
|
||||
SaveTempsNone,
|
||||
SaveTempsCwd,
|
||||
SaveTempsObj
|
||||
} SaveTemps;
|
||||
|
||||
public:
|
||||
// Diag - Forwarding function for diagnostics.
|
||||
DiagnosticBuilder Diag(unsigned DiagID) const {
|
||||
|
@ -232,6 +238,9 @@ public:
|
|||
InstalledDir = Value;
|
||||
}
|
||||
|
||||
bool isSaveTempsEnabled() const { return SaveTemps != SaveTempsNone; }
|
||||
bool isSaveTempsObj() const { return SaveTemps == SaveTempsObj; }
|
||||
|
||||
/// @}
|
||||
/// @name Primary Functionality
|
||||
/// @{
|
||||
|
|
|
@ -1454,7 +1454,10 @@ def resource_dir_EQ : Joined<["-"], "resource-dir=">, Flags<[DriverOption]>,
|
|||
def rpath : Separate<["-"], "rpath">, Flags<[LinkerInput]>;
|
||||
def rtlib_EQ : Joined<["-", "--"], "rtlib=">;
|
||||
def r : Flag<["-"], "r">;
|
||||
def save_temps_EQ : Joined<["-", "--"], "save-temps=">, Flags<[DriverOption]>,
|
||||
HelpText<"Save intermediate compilation results.">;
|
||||
def save_temps : Flag<["-", "--"], "save-temps">, Flags<[DriverOption]>,
|
||||
Alias<save_temps_EQ>, AliasArgs<["cwd"]>,
|
||||
HelpText<"Save intermediate compilation results">;
|
||||
def via_file_asm : Flag<["-", "--"], "via-file-asm">, InternalDebugOpt,
|
||||
HelpText<"Write assembly to file for input to assemble jobs">;
|
||||
|
|
|
@ -44,19 +44,17 @@ using namespace clang::driver;
|
|||
using namespace clang;
|
||||
using namespace llvm::opt;
|
||||
|
||||
Driver::Driver(StringRef ClangExecutable,
|
||||
StringRef DefaultTargetTriple,
|
||||
Driver::Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple,
|
||||
DiagnosticsEngine &Diags)
|
||||
: Opts(createDriverOptTable()), Diags(Diags), Mode(GCCMode),
|
||||
ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
|
||||
UseStdLib(true), DefaultTargetTriple(DefaultTargetTriple),
|
||||
DriverTitle("clang LLVM compiler"),
|
||||
CCPrintOptionsFilename(nullptr), CCPrintHeadersFilename(nullptr),
|
||||
CCLogDiagnosticsFilename(nullptr),
|
||||
CCCPrintBindings(false),
|
||||
CCPrintHeaders(false), CCLogDiagnostics(false),
|
||||
CCGenDiagnostics(false), CCCGenericGCCName(""), CheckInputsExist(true),
|
||||
CCCUsePCH(true), SuppressMissingInputWarning(false) {
|
||||
: Opts(createDriverOptTable()), Diags(Diags), Mode(GCCMode),
|
||||
SaveTemps(SaveTempsNone), ClangExecutable(ClangExecutable),
|
||||
SysRoot(DEFAULT_SYSROOT), UseStdLib(true),
|
||||
DefaultTargetTriple(DefaultTargetTriple),
|
||||
DriverTitle("clang LLVM compiler"), CCPrintOptionsFilename(nullptr),
|
||||
CCPrintHeadersFilename(nullptr), CCLogDiagnosticsFilename(nullptr),
|
||||
CCCPrintBindings(false), CCPrintHeaders(false), CCLogDiagnostics(false),
|
||||
CCGenDiagnostics(false), CCCGenericGCCName(""), CheckInputsExist(true),
|
||||
CCCUsePCH(true), SuppressMissingInputWarning(false) {
|
||||
|
||||
Name = llvm::sys::path::stem(ClangExecutable);
|
||||
Dir = llvm::sys::path::parent_path(ClangExecutable);
|
||||
|
@ -364,6 +362,13 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
|
|||
if (const Arg *A = Args->getLastArg(options::OPT_resource_dir))
|
||||
ResourceDir = A->getValue();
|
||||
|
||||
if (const Arg *A = Args->getLastArg(options::OPT_save_temps_EQ)) {
|
||||
SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
|
||||
.Case("cwd", SaveTempsCwd)
|
||||
.Case("obj", SaveTempsObj)
|
||||
.Default(SaveTempsCwd);
|
||||
}
|
||||
|
||||
// Perform the default argument translations.
|
||||
DerivedArgList *TranslatedArgs = TranslateInputArgs(*Args);
|
||||
|
||||
|
@ -504,7 +509,7 @@ void Driver::generateCompilationDiagnostics(Compilation &C,
|
|||
|
||||
// If any of the preprocessing commands failed, clean up and exit.
|
||||
if (!FailingCommands.empty()) {
|
||||
if (!C.getArgs().hasArg(options::OPT_save_temps))
|
||||
if (!isSaveTempsEnabled())
|
||||
C.CleanupFileList(C.getTempFiles(), true);
|
||||
|
||||
Diag(clang::diag::note_drv_command_failed_diag_msg)
|
||||
|
@ -612,7 +617,7 @@ int Driver::ExecuteCompilation(Compilation &C,
|
|||
const Command *FailingCommand = it->second;
|
||||
|
||||
// Remove result files if we're not saving temps.
|
||||
if (!C.getArgs().hasArg(options::OPT_save_temps)) {
|
||||
if (!isSaveTempsEnabled()) {
|
||||
const JobAction *JA = cast<JobAction>(&FailingCommand->getSource());
|
||||
C.CleanupFileMap(C.getResultFiles(), JA, true);
|
||||
|
||||
|
@ -1471,8 +1476,8 @@ void Driver::BuildJobs(Compilation &C) const {
|
|||
}
|
||||
}
|
||||
|
||||
static const Tool *SelectToolForJob(Compilation &C, const ToolChain *TC,
|
||||
const JobAction *JA,
|
||||
static const Tool *SelectToolForJob(Compilation &C, bool SaveTemps,
|
||||
const ToolChain *TC, const JobAction *JA,
|
||||
const ActionList *&Inputs) {
|
||||
const Tool *ToolForJob = nullptr;
|
||||
|
||||
|
@ -1481,7 +1486,7 @@ static const Tool *SelectToolForJob(Compilation &C, const ToolChain *TC,
|
|||
// compiler input.
|
||||
|
||||
if (TC->useIntegratedAs() &&
|
||||
!C.getArgs().hasArg(options::OPT_save_temps) &&
|
||||
!SaveTemps &&
|
||||
!C.getArgs().hasArg(options::OPT_via_file_asm) &&
|
||||
!C.getArgs().hasArg(options::OPT__SLASH_FA) &&
|
||||
!C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
|
||||
|
@ -1512,8 +1517,7 @@ static const Tool *SelectToolForJob(Compilation &C, const ToolChain *TC,
|
|||
const Tool *Compiler = TC->SelectTool(*CompileJA);
|
||||
if (!Compiler)
|
||||
return nullptr;
|
||||
if (!Compiler->canEmitIR() ||
|
||||
!C.getArgs().hasArg(options::OPT_save_temps)) {
|
||||
if (!Compiler->canEmitIR() || !SaveTemps) {
|
||||
Inputs = &(*Inputs)[0]->getInputs();
|
||||
ToolForJob = Compiler;
|
||||
}
|
||||
|
@ -1529,7 +1533,7 @@ static const Tool *SelectToolForJob(Compilation &C, const ToolChain *TC,
|
|||
if (Inputs->size() == 1 && isa<PreprocessJobAction>(*Inputs->begin()) &&
|
||||
!C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
|
||||
!C.getArgs().hasArg(options::OPT_traditional_cpp) &&
|
||||
!C.getArgs().hasArg(options::OPT_save_temps) &&
|
||||
!SaveTemps &&
|
||||
!C.getArgs().hasArg(options::OPT_rewrite_objc) &&
|
||||
ToolForJob->hasIntegratedCPP())
|
||||
Inputs = &(*Inputs)[0]->getInputs();
|
||||
|
@ -1577,7 +1581,7 @@ void Driver::BuildJobsForAction(Compilation &C,
|
|||
const ActionList *Inputs = &A->getInputs();
|
||||
|
||||
const JobAction *JA = cast<JobAction>(A);
|
||||
const Tool *T = SelectToolForJob(C, TC, JA, Inputs);
|
||||
const Tool *T = SelectToolForJob(C, isSaveTempsEnabled(), TC, JA, Inputs);
|
||||
if (!T)
|
||||
return;
|
||||
|
||||
|
@ -1708,7 +1712,7 @@ const char *Driver::GetNamedOutputPath(Compilation &C,
|
|||
}
|
||||
|
||||
// Output to a temporary file?
|
||||
if ((!AtTopLevel && !C.getArgs().hasArg(options::OPT_save_temps) &&
|
||||
if ((!AtTopLevel && !isSaveTempsEnabled() &&
|
||||
!C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
|
||||
CCGenDiagnostics) {
|
||||
StringRef Name = llvm::sys::path::filename(BaseInput);
|
||||
|
@ -1780,11 +1784,20 @@ const char *Driver::GetNamedOutputPath(Compilation &C,
|
|||
NamedOutput = C.getArgs().MakeArgString(Suffixed.c_str());
|
||||
}
|
||||
|
||||
// Prepend object file path if -save-temps=obj
|
||||
if (!AtTopLevel && isSaveTempsObj() && C.getArgs().hasArg(options::OPT_o) &&
|
||||
JA.getType() != types::TY_PCH) {
|
||||
Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o);
|
||||
SmallString<128> TempPath(FinalOutput->getValue());
|
||||
llvm::sys::path::remove_filename(TempPath);
|
||||
StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
|
||||
llvm::sys::path::append(TempPath, OutputFileName);
|
||||
NamedOutput = C.getArgs().MakeArgString(TempPath.c_str());
|
||||
}
|
||||
|
||||
// If we're saving temps and the temp file conflicts with the input file,
|
||||
// then avoid overwriting input file.
|
||||
if (!AtTopLevel && C.getArgs().hasArg(options::OPT_save_temps) &&
|
||||
NamedOutput == BaseName) {
|
||||
|
||||
if (!AtTopLevel && isSaveTempsEnabled() && NamedOutput == BaseName) {
|
||||
bool SameFile = false;
|
||||
SmallString<256> Result;
|
||||
llvm::sys::fs::current_path(Result);
|
||||
|
|
|
@ -4495,7 +4495,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
// With -save-temps, we want to save the unoptimized bitcode output from the
|
||||
// CompileJobAction, so disable optimizations if they are not already
|
||||
// disabled.
|
||||
if (Args.hasArg(options::OPT_save_temps) && !OptDisabled &&
|
||||
if (C.getDriver().isSaveTempsEnabled() && !OptDisabled &&
|
||||
isa<CompileJobAction>(JA))
|
||||
CmdArgs.push_back("-disable-llvm-optzns");
|
||||
|
||||
|
|
|
@ -5,7 +5,18 @@
|
|||
// CHECK: "-o" "save-temps.bc"
|
||||
// CHECK: "-o" "save-temps.s"
|
||||
// CHECK: "-o" "save-temps.o"
|
||||
// CHECK: "-o" "a.out"
|
||||
// CHECK: "-o" "a.out"
|
||||
|
||||
// Check -save-temps=cwd which should work the same as -save-temps above
|
||||
//
|
||||
// RUN: %clang -target x86_64-apple-darwin -save-temps=cwd -arch x86_64 %s -### 2>&1 \
|
||||
// RUN: | FileCheck %s -check-prefix=CWD
|
||||
// CWD: "-o" "save-temps.i"
|
||||
// CWD: "-disable-llvm-optzns"
|
||||
// CWD: "-o" "save-temps.bc"
|
||||
// CWD: "-o" "save-temps.s"
|
||||
// CWD: "-o" "save-temps.o"
|
||||
// CWD: "-o" "a.out"
|
||||
|
||||
// Check for a single clang cc1 invocation when NOT using -save-temps.
|
||||
// RUN: %clang -target x86_64-apple-darwin -arch x86_64 -S %s -### 2>&1 \
|
||||
|
@ -20,11 +31,47 @@
|
|||
// MULT-ARCH: "-o" "save-temps-i386.bc"
|
||||
// MULT-ARCH: "-o" "save-temps-i386.s"
|
||||
// MULT-ARCH: "-o" "save-temps-i386.o"
|
||||
// MULT-ARCH: "-o" "a.out-i386"
|
||||
// MULT-ARCH: "-o" "a.out-i386"
|
||||
// MULT-ARCH: "-o" "save-temps-x86_64.i"
|
||||
// MULT-ARCH: "-o" "save-temps-x86_64.bc"
|
||||
// MULT-ARCH: "-o" "save-temps-x86_64.s"
|
||||
// MULT-ARCH: "-o" "save-temps-x86_64.o"
|
||||
// MULT-ARCH: "-o" "a.out-x86_64"
|
||||
// MULT-ARCH: "-o" "a.out-x86_64"
|
||||
// MULT-ARCH: lipo
|
||||
// MULT-ARCH: "-create" "-output" "a.out" "a.out-i386" "a.out-x86_64"
|
||||
|
||||
// RUN: %clang -target x86_64-apple-darwin -save-temps=cwd -arch i386 -arch x86_64 %s -### 2>&1 \
|
||||
// RUN: | FileCheck %s -check-prefix=MULT-ARCH-CWD
|
||||
// MULT-ARCH-CWD: "-o" "save-temps-i386.i"
|
||||
// MULT-ARCH-CWD: "-o" "save-temps-i386.bc"
|
||||
// MULT-ARCH-CWD: "-o" "save-temps-i386.s"
|
||||
// MULT-ARCH-CWD: "-o" "save-temps-i386.o"
|
||||
// MULT-ARCH-CWD: "-o" "a.out-i386"
|
||||
// MULT-ARCH-CWD: "-o" "save-temps-x86_64.i"
|
||||
// MULT-ARCH-CWD: "-o" "save-temps-x86_64.bc"
|
||||
// MULT-ARCH-CWD: "-o" "save-temps-x86_64.s"
|
||||
// MULT-ARCH-CWD: "-o" "save-temps-x86_64.o"
|
||||
// MULT-ARCH-CWD: "-o" "a.out-x86_64"
|
||||
// MULT-ARCH-CWD: lipo
|
||||
// MULT-ARCH-CWD: "-create" "-output" "a.out" "a.out-i386" "a.out-x86_64"
|
||||
|
||||
// Check that temp files are saved in the same directory as the output file
|
||||
// regardless of whether -o is specified.
|
||||
//
|
||||
// RUN: %clang -target x86_64-apple-darwin -save-temps=obj -o obj/dir/a.out -arch x86_64 %s -### 2>&1 \
|
||||
// RUN: | FileCheck %s -check-prefix=CHECK-OBJ
|
||||
// CHECK-OBJ: "-o" "obj/dir{{/|\\\\}}save-temps.i"
|
||||
// CHECK-OBJ: "-disable-llvm-optzns"
|
||||
// CHECK-OBJ: "-o" "obj/dir{{/|\\\\}}save-temps.bc"
|
||||
// CHECK-OBJ: "-o" "obj/dir{{/|\\\\}}save-temps.s"
|
||||
// CHECK-OBJ: "-o" "obj/dir{{/|\\\\}}save-temps.o"
|
||||
// CHECK-OBJ: "-o" "obj/dir{{/|\\\\}}a.out"
|
||||
//
|
||||
// RUN: %clang -target x86_64-apple-darwin -save-temps=obj -arch x86_64 %s -### 2>&1 \
|
||||
// RUN: | FileCheck %s -check-prefix=CHECK-OBJ-NOO
|
||||
// CHECK-OBJ-NOO: "-o" "save-temps.i"
|
||||
// CHECK-OBJ-NOO: "-disable-llvm-optzns"
|
||||
// CHECK-OBJ-NOO: "-o" "save-temps.bc"
|
||||
// CHECK-OBJ-NOO: "-o" "save-temps.s"
|
||||
// CHECK-OBJ-NOO: "-o" "save-temps.o"
|
||||
// CHECK-OBJ-NOO: "-o" "a.out"
|
||||
|
|
Loading…
Reference in New Issue