[cfe-commits] r173361 - in /cfe/trunk: include/clang/Driver/Compilation.h include/clang/Driver/Util.h lib/Driver/Compilation.cpp lib/Driver/Driver.cpp lib/Driver/Tools.cpp lib/Driver/Tools.h test/Driver/output-file-cleanup.c
Chad Rosier
mcrosier at apple.com
Thu Jan 24 11:14:47 PST 2013
Author: mcrosier
Date: Thu Jan 24 13:14:47 2013
New Revision: 173361
URL: http://llvm.org/viewvc/llvm-project?rev=173361&view=rev
Log:
[driver] Associate a JobAction with each result file. This enables the driver
to delete result files for only those commands that fail.
Part of rdar://12984531
Modified:
cfe/trunk/include/clang/Driver/Compilation.h
cfe/trunk/include/clang/Driver/Util.h
cfe/trunk/lib/Driver/Compilation.cpp
cfe/trunk/lib/Driver/Driver.cpp
cfe/trunk/lib/Driver/Tools.cpp
cfe/trunk/lib/Driver/Tools.h
cfe/trunk/test/Driver/output-file-cleanup.c
Modified: cfe/trunk/include/clang/Driver/Compilation.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Compilation.h?rev=173361&r1=173360&r2=173361&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Compilation.h (original)
+++ cfe/trunk/include/clang/Driver/Compilation.h Thu Jan 24 13:14:47 2013
@@ -20,6 +20,7 @@
class DerivedArgList;
class Driver;
class InputArgList;
+ class JobAction;
class JobList;
class ToolChain;
@@ -54,11 +55,11 @@
ArgStringList TempFiles;
/// Result files which should be removed on failure.
- ArgStringList ResultFiles;
+ ArgStringMap ResultFiles;
/// Result files which are generated correctly on failure, and which should
/// only be removed if we crash.
- ArgStringList FailureResultFiles;
+ ArgStringMap FailureResultFiles;
/// Redirection for stdout, stderr, etc.
const llvm::sys::Path **Redirects;
@@ -88,9 +89,9 @@
const ArgStringList &getTempFiles() const { return TempFiles; }
- const ArgStringList &getResultFiles() const { return ResultFiles; }
+ const ArgStringMap &getResultFiles() const { return ResultFiles; }
- const ArgStringList &getFailureResultFiles() const {
+ const ArgStringMap &getFailureResultFiles() const {
return FailureResultFiles;
}
@@ -113,24 +114,40 @@
/// addResultFile - Add a file to remove on failure, and returns its
/// argument.
- const char *addResultFile(const char *Name) {
- ResultFiles.push_back(Name);
+ const char *addResultFile(const char *Name, const JobAction *JA) {
+ ResultFiles[JA] = Name;
return Name;
}
/// addFailureResultFile - Add a file to remove if we crash, and returns its
/// argument.
- const char *addFailureResultFile(const char *Name) {
- FailureResultFiles.push_back(Name);
+ const char *addFailureResultFile(const char *Name, const JobAction *JA) {
+ FailureResultFiles[JA] = Name;
return Name;
}
+ /// CleanupFile - Delete a given file.
+ ///
+ /// \param IssueErrors - Report failures as errors.
+ /// \return Whether the file was removed successfully.
+ bool CleanupFile(const char *File, bool IssueErrors = false) const;
+
/// CleanupFileList - Remove the files in the given list.
///
/// \param IssueErrors - Report failures as errors.
/// \return Whether all files were removed successfully.
bool CleanupFileList(const ArgStringList &Files,
- bool IssueErrors=false) const;
+ bool IssueErrors = false) const;
+
+ /// CleanupFileMap - Remove the files in the given map.
+ ///
+ /// \param JA - If specified, only delete the files associated with this
+ /// JobAction. Otherwise, delete all files in the map.
+ /// \param IssueErrors - Report failures as errors.
+ /// \return Whether all files were removed successfully.
+ bool CleanupFileMap(const ArgStringMap &Files,
+ const JobAction *JA,
+ bool IssueErrors = false) const;
/// PrintJob - Print one job in -### format.
///
Modified: cfe/trunk/include/clang/Driver/Util.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Util.h?rev=173361&r1=173360&r2=173361&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Util.h (original)
+++ cfe/trunk/include/clang/Driver/Util.h Thu Jan 24 13:14:47 2013
@@ -11,14 +11,19 @@
#define CLANG_DRIVER_UTIL_H_
#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DenseMap.h"
namespace clang {
namespace driver {
class Action;
+ class JobAction;
/// ArgStringList - Type used for constructing argv lists for subprocesses.
typedef SmallVector<const char*, 16> ArgStringList;
+ /// ArgStringMap - Type used to map a JobAction to its result file.
+ typedef llvm::DenseMap<const JobAction*, const char*> ArgStringMap;
+
/// ActionList - Type used for lists of actions.
typedef SmallVector<Action*, 3> ActionList;
Modified: cfe/trunk/lib/Driver/Compilation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Compilation.cpp?rev=173361&r1=173360&r2=173361&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Compilation.cpp (original)
+++ cfe/trunk/lib/Driver/Compilation.cpp Thu Jan 24 13:14:47 2013
@@ -199,39 +199,56 @@
}
}
+bool Compilation::CleanupFile(const char *File, bool IssueErrors) const {
+ llvm::sys::Path P(File);
+ std::string Error;
+
+ // Don't try to remove files which we don't have write access to (but may be
+ // able to remove), or non-regular files. Underlying tools may have
+ // intentionally not overwritten them.
+ if (!P.canWrite() || !P.isRegularFile())
+ return true;
+
+ if (P.eraseFromDisk(false, &Error)) {
+ // Failure is only failure if the file exists and is "regular". There is
+ // a race condition here due to the limited interface of
+ // llvm::sys::Path, we want to know if the removal gave ENOENT.
+
+ // FIXME: Grumble, P.exists() is broken. PR3837.
+ struct stat buf;
+ if (::stat(P.c_str(), &buf) == 0 ? (buf.st_mode & S_IFMT) == S_IFREG :
+ (errno != ENOENT)) {
+ if (IssueErrors)
+ getDriver().Diag(clang::diag::err_drv_unable_to_remove_file)
+ << Error;
+ return false;
+ }
+ }
+ return true;
+}
+
bool Compilation::CleanupFileList(const ArgStringList &Files,
bool IssueErrors) const {
bool Success = true;
-
for (ArgStringList::const_iterator
- it = Files.begin(), ie = Files.end(); it != ie; ++it) {
+ it = Files.begin(), ie = Files.end(); it != ie; ++it)
+ Success &= CleanupFile(*it, IssueErrors);
+ return Success;
+}
- llvm::sys::Path P(*it);
- std::string Error;
+bool Compilation::CleanupFileMap(const ArgStringMap &Files,
+ const JobAction *JA,
+ bool IssueErrors) const {
+ bool Success = true;
+ for (ArgStringMap::const_iterator
+ it = Files.begin(), ie = Files.end(); it != ie; ++it) {
- // Don't try to remove files which we don't have write access to (but may be
- // able to remove), or non-regular files. Underlying tools may have
- // intentionally not overwritten them.
- if (!P.canWrite() || !P.isRegularFile())
+ // If specified, only delete the files associated with the JobAction.
+ // Otherwise, delete all files in the map.
+ if (JA && it->first != JA)
continue;
-
- if (P.eraseFromDisk(false, &Error)) {
- // Failure is only failure if the file exists and is "regular". There is
- // a race condition here due to the limited interface of
- // llvm::sys::Path, we want to know if the removal gave ENOENT.
-
- // FIXME: Grumble, P.exists() is broken. PR3837.
- struct stat buf;
- if (::stat(P.c_str(), &buf) == 0 ? (buf.st_mode & S_IFMT) == S_IFREG :
- (errno != ENOENT)) {
- if (IssueErrors)
- getDriver().Diag(clang::diag::err_drv_unable_to_remove_file)
- << Error;
- Success = false;
- }
- }
+ Success &= CleanupFile(it->second, IssueErrors);
}
-
return Success;
}
Modified: cfe/trunk/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=173361&r1=173360&r2=173361&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Driver.cpp (original)
+++ cfe/trunk/lib/Driver/Driver.cpp Thu Jan 24 13:14:47 2013
@@ -485,8 +485,9 @@
<< "\n\n********************";
} else {
// Failure, remove preprocessed files.
- if (!C.getArgs().hasArg(options::OPT_save_temps))
+ if (!C.getArgs().hasArg(options::OPT_save_temps)) {
C.CleanupFileList(C.getTempFiles(), true);
+ }
Diag(clang::diag::note_drv_command_failed_diag_msg)
<< "Error generating preprocessed source(s).";
@@ -516,11 +517,12 @@
// Otherwise, remove result files as well.
if (!C.getArgs().hasArg(options::OPT_save_temps)) {
- C.CleanupFileList(C.getResultFiles(), true);
+ const JobAction *JA = cast<JobAction>(&FailingCommand->getSource());
+ C.CleanupFileMap(C.getResultFiles(), JA, true);
// Failure result files are valid unless we crashed.
if (Res < 0)
- C.CleanupFileList(C.getFailureResultFiles(), true);
+ C.CleanupFileMap(C.getFailureResultFiles(), JA, true);
}
// Print extra information about abnormal failures, if possible.
@@ -1417,7 +1419,7 @@
if (AtTopLevel && !isa<DsymutilJobAction>(JA) &&
!isa<VerifyJobAction>(JA)) {
if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o))
- return C.addResultFile(FinalOutput->getValue());
+ return C.addResultFile(FinalOutput->getValue(), &JA);
}
// Default to writing to stdout?
@@ -1487,9 +1489,9 @@
BasePath = NamedOutput;
else
llvm::sys::path::append(BasePath, NamedOutput);
- return C.addResultFile(C.getArgs().MakeArgString(BasePath.c_str()));
+ return C.addResultFile(C.getArgs().MakeArgString(BasePath.c_str()), &JA);
} else {
- return C.addResultFile(NamedOutput);
+ return C.addResultFile(NamedOutput, &JA);
}
}
Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=173361&r1=173360&r2=173361&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Thu Jan 24 13:14:47 2013
@@ -228,6 +228,7 @@
}
void Clang::AddPreprocessingOptions(Compilation &C,
+ const JobAction &JA,
const Driver &D,
const ArgList &Args,
ArgStringList &CmdArgs,
@@ -248,7 +249,7 @@
const char *DepFile;
if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
DepFile = MF->getValue();
- C.addFailureResultFile(DepFile);
+ C.addFailureResultFile(DepFile, &JA);
} else if (Output.getType() == types::TY_Dependencies) {
DepFile = Output.getFilename();
} else if (A->getOption().matches(options::OPT_M) ||
@@ -256,7 +257,7 @@
DepFile = "-";
} else {
DepFile = getDependencyFileName(Args, Inputs);
- C.addFailureResultFile(DepFile);
+ C.addFailureResultFile(DepFile, &JA);
}
CmdArgs.push_back("-dependency-file");
CmdArgs.push_back(DepFile);
@@ -2300,7 +2301,7 @@
//
// FIXME: Support -fpreprocessed
if (types::getPreprocessedType(InputType) != types::TY_INVALID)
- AddPreprocessingOptions(C, D, Args, CmdArgs, Output, Inputs);
+ AddPreprocessingOptions(C, JA, D, Args, CmdArgs, Output, Inputs);
// Don't warn about "clang -c -DPIC -fPIC test.i" because libtool.m4 assumes
// that "The compiler can only warn and ignore the option if not recognized".
Modified: cfe/trunk/lib/Driver/Tools.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.h?rev=173361&r1=173360&r2=173361&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.h (original)
+++ cfe/trunk/lib/Driver/Tools.h Thu Jan 24 13:14:47 2013
@@ -40,6 +40,7 @@
private:
void AddPreprocessingOptions(Compilation &C,
+ const JobAction &JA,
const Driver &D,
const ArgList &Args,
ArgStringList &CmdArgs,
Modified: cfe/trunk/test/Driver/output-file-cleanup.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/output-file-cleanup.c?rev=173361&r1=173360&r2=173361&view=diff
==============================================================================
--- cfe/trunk/test/Driver/output-file-cleanup.c (original)
+++ cfe/trunk/test/Driver/output-file-cleanup.c Thu Jan 24 13:14:47 2013
@@ -1,15 +1,15 @@
// RUN: touch %t.o
-// RUN: not %clang -DCRASH -o %t.o -MMD -MF %t.d %s
+// RUN: not %clang -c -DCRASH -o %t.o -MMD -MF %t.d %s
// RUN: test ! -f %t.o
// RUN: test ! -f %t.d
// RUN: touch %t.o
-// RUN: not %clang -DMISSING -o %t.o -MMD -MF %t.d %s
+// RUN: not %clang -c -DMISSING -o %t.o -MMD -MF %t.d %s
// RUN: test ! -f %t.o
// RUN: test ! -f %t.d
// RUN: touch %t.o
-// RUN: not %clang -o %t.o -MMD -MF %t.d %s
+// RUN: not %clang -c -o %t.o -MMD -MF %t.d %s
// RUN: test ! -f %t.o
// RUN: test -f %t.d
@@ -23,3 +23,16 @@
#else
invalid C code
#endif
+
+// RUN: touch %t1.c
+// RUN: echo "invalid C code" > %t2.c
+// RUN: cd %T && not %clang -c %t1.c %t2.c
+// RUN: test -f %t1.o
+// RUN: test ! -f %t2.o
+
+// RUN: touch %t1.c
+// RUN: touch %t2.c
+// RUN: chmod -r %t2.c
+// RUN: cd %T && not %clang -c %t1.c %t2.c
+// RUN: test -f %t1.o
+// RUN: test ! -f %t2.o
More information about the cfe-commits
mailing list