Author: rnk Date: Mon Feb 2 16:41:48 2015 New Revision: 227886 URL: http://llvm.org/viewvc/llvm-project?rev=227886&view=rev Log: 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 Modified: cfe/trunk/include/clang/Driver/Driver.h cfe/trunk/include/clang/Driver/Options.td cfe/trunk/lib/Driver/Driver.cpp cfe/trunk/lib/Driver/Tools.cpp cfe/trunk/test/Driver/save-temps.c Modified: cfe/trunk/include/clang/Driver/Driver.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Driver.h?rev=227886&r1=227885&r2=227886&view=diff ============================================================================== --- cfe/trunk/include/clang/Driver/Driver.h (original) +++ cfe/trunk/include/clang/Driver/Driver.h Mon Feb 2 16:41:48 2015 @@ -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 /// @{ Modified: cfe/trunk/include/clang/Driver/Options.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=227886&r1=227885&r2=227886&view=diff ============================================================================== --- cfe/trunk/include/clang/Driver/Options.td (original) +++ cfe/trunk/include/clang/Driver/Options.td Mon Feb 2 16:41:48 2015 @@ -1454,7 +1454,10 @@ def resource_dir_EQ : Joined<["-"], "res 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">; Modified: cfe/trunk/lib/Driver/Driver.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=227886&r1=227885&r2=227886&view=diff ============================================================================== --- cfe/trunk/lib/Driver/Driver.cpp (original) +++ cfe/trunk/lib/Driver/Driver.cpp Mon Feb 2 16:41:48 2015 @@ -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(Ar 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::generateCompilationDiagnost // 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(Compilati 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) c } } -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(Comp // 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(Comp 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(Comp 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(Compilat 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(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(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); Modified: cfe/trunk/lib/Driver/Tools.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=227886&r1=227885&r2=227886&view=diff ============================================================================== --- cfe/trunk/lib/Driver/Tools.cpp (original) +++ cfe/trunk/lib/Driver/Tools.cpp Mon Feb 2 16:41:48 2015 @@ -4495,7 +4495,7 @@ void Clang::ConstructJob(Compilation &C, // 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"); Modified: cfe/trunk/test/Driver/save-temps.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/save-temps.c?rev=227886&r1=227885&r2=227886&view=diff ============================================================================== --- cfe/trunk/test/Driver/save-temps.c (original) +++ cfe/trunk/test/Driver/save-temps.c Mon Feb 2 16:41:48 2015 @@ -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" _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
