]> granicus.if.org Git - clang/commitdiff
Delete the depfile if we could not open a header file. We cannot
authorPeter Collingbourne <peter@pcc.me.uk>
Mon, 21 Nov 2011 00:01:14 +0000 (00:01 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Mon, 21 Nov 2011 00:01:14 +0000 (00:01 +0000)
generate any reasonable depfile if a header is missing.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145019 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Frontend/DependencyFile.cpp
test/Driver/output-file-cleanup.c

index ff3a12392c9f8f9660cfcfd5e53906d44f995899..21f5daa9ee39eac403efb738d2dfcd3e172b9213 100644 (file)
@@ -31,11 +31,12 @@ class DependencyFileCallback : public PPCallbacks {
   std::vector<std::string> Files;
   llvm::StringSet<> FilesSet;
   const Preprocessor *PP;
+  std::string OutputFile;
   std::vector<std::string> Targets;
-  raw_ostream *OS;
   bool IncludeSystemHeaders;
   bool PhonyTarget;
   bool AddMissingHeaderDeps;
+  bool SeenMissingHeader;
 private:
   bool FileMatchesDepCriteria(const char *Filename,
                               SrcMgr::CharacteristicKind FileType);
@@ -44,12 +45,12 @@ private:
 
 public:
   DependencyFileCallback(const Preprocessor *_PP,
-                         raw_ostream *_OS,
                          const DependencyOutputOptions &Opts)
-    : PP(_PP), Targets(Opts.Targets), OS(_OS),
+    : PP(_PP), OutputFile(Opts.OutputFile), Targets(Opts.Targets),
       IncludeSystemHeaders(Opts.IncludeSystemHeaders),
       PhonyTarget(Opts.UsePhonyTargets),
-      AddMissingHeaderDeps(Opts.AddMissingHeaderDeps) {}
+      AddMissingHeaderDeps(Opts.AddMissingHeaderDeps),
+      SeenMissingHeader(false) {}
 
   virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
                            SrcMgr::CharacteristicKind FileType,
@@ -65,8 +66,6 @@ public:
 
   virtual void EndOfMainFile() {
     OutputDependencyFile();
-    delete OS;
-    OS = 0;
   }
 };
 }
@@ -78,19 +77,11 @@ void clang::AttachDependencyFileGen(Preprocessor &PP,
     return;
   }
 
-  std::string Err;
-  raw_ostream *OS(new llvm::raw_fd_ostream(Opts.OutputFile.c_str(), Err));
-  if (!Err.empty()) {
-    PP.getDiagnostics().Report(diag::err_fe_error_opening)
-      << Opts.OutputFile << Err;
-    return;
-  }
-
   // Disable the "file not found" diagnostic if the -MG option was given.
   if (Opts.AddMissingHeaderDeps)
     PP.SetSuppressIncludeNotFoundError(true);
 
-  PP.addPPCallbacks(new DependencyFileCallback(&PP, OS, Opts));
+  PP.addPPCallbacks(new DependencyFileCallback(&PP, Opts));
 }
 
 /// FileMatchesDepCriteria - Determine whether the given Filename should be
@@ -145,8 +136,12 @@ void DependencyFileCallback::InclusionDirective(SourceLocation HashLoc,
                                                 SourceLocation EndLoc,
                                                 StringRef SearchPath,
                                                 StringRef RelativePath) {
-  if (AddMissingHeaderDeps && !File)
-    AddFilename(FileName);
+  if (!File) {
+    if (AddMissingHeaderDeps)
+      AddFilename(FileName);
+    else
+      SeenMissingHeader = true;
+  }
 }
 
 void DependencyFileCallback::AddFilename(StringRef Filename) {
@@ -165,6 +160,19 @@ static void PrintFilename(raw_ostream &OS, StringRef Filename) {
 }
 
 void DependencyFileCallback::OutputDependencyFile() {
+  if (SeenMissingHeader) {
+    llvm::sys::Path(OutputFile).eraseFromDisk();
+    return;
+  }
+
+  std::string Err;
+  llvm::raw_fd_ostream OS(OutputFile.c_str(), Err);
+  if (!Err.empty()) {
+    PP->getDiagnostics().Report(diag::err_fe_error_opening)
+      << OutputFile << Err;
+    return;
+  }
+
   // Write out the dependency targets, trying to avoid overly long
   // lines when possible. We try our best to emit exactly the same
   // dependency file as GCC (4.2), assuming the included files are the
@@ -179,16 +187,16 @@ void DependencyFileCallback::OutputDependencyFile() {
       Columns += N;
     } else if (Columns + N + 2 > MaxColumns) {
       Columns = N + 2;
-      *OS << " \\\n  ";
+      OS << " \\\n  ";
     } else {
       Columns += N + 1;
-      *OS << ' ';
+      OS << ' ';
     }
     // Targets already quoted as needed.
-    *OS << *I;
+    OS << *I;
   }
 
-  *OS << ':';
+  OS << ':';
   Columns += 1;
 
   // Now add each dependency in the order it was seen, but avoiding
@@ -200,23 +208,23 @@ void DependencyFileCallback::OutputDependencyFile() {
     // break the line on the next iteration.
     unsigned N = I->length();
     if (Columns + (N + 1) + 2 > MaxColumns) {
-      *OS << " \\\n ";
+      OS << " \\\n ";
       Columns = 2;
     }
-    *OS << ' ';
-    PrintFilename(*OS, *I);
+    OS << ' ';
+    PrintFilename(OS, *I);
     Columns += N + 1;
   }
-  *OS << '\n';
+  OS << '\n';
 
   // Create phony targets if requested.
   if (PhonyTarget && !Files.empty()) {
     // Skip the first entry, this is always the input file itself.
     for (std::vector<std::string>::iterator I = Files.begin() + 1,
            E = Files.end(); I != E; ++I) {
-      *OS << '\n';
-      PrintFilename(*OS, *I);
-      *OS << ":\n";
+      OS << '\n';
+      PrintFilename(OS, *I);
+      OS << ":\n";
     }
   }
 }
index b4745e22473389731a8af625400b27ee0eba5e19..7bc17af20303e48faa8ec53f0d692b0e62cc1884 100644 (file)
@@ -3,6 +3,11 @@
 // 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: 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: test ! -f %t.o
@@ -15,6 +20,8 @@
 
 #ifdef CRASH
 #pragma clang __debug crash
+#elif defined(MISSING)
+#include "nonexistent.h"
 #else
 invalid C code
 #endif