Implement -MG.  Fixes PR9613

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134996 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/DependencyFile.cpp b/lib/Frontend/DependencyFile.cpp
index dde3454..1edd09b 100644
--- a/lib/Frontend/DependencyFile.cpp
+++ b/lib/Frontend/DependencyFile.cpp
@@ -17,6 +17,7 @@
 #include "clang/Frontend/DependencyOutputOptions.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Lex/DirectoryLookup.h"
+#include "clang/Lex/LexDiagnostic.h"
 #include "clang/Lex/PPCallbacks.h"
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/StringSet.h"
@@ -34,9 +35,11 @@
   llvm::raw_ostream *OS;
   bool IncludeSystemHeaders;
   bool PhonyTarget;
+  bool AddMissingHeaderDeps;
 private:
   bool FileMatchesDepCriteria(const char *Filename,
                               SrcMgr::CharacteristicKind FileType);
+  void AddFilename(llvm::StringRef Filename);
   void OutputDependencyFile();
 
 public:
@@ -45,10 +48,19 @@
                          const DependencyOutputOptions &Opts)
     : PP(_PP), Targets(Opts.Targets), OS(_OS),
       IncludeSystemHeaders(Opts.IncludeSystemHeaders),
-      PhonyTarget(Opts.UsePhonyTargets) {}
+      PhonyTarget(Opts.UsePhonyTargets),
+      AddMissingHeaderDeps(Opts.AddMissingHeaderDeps) {}
 
   virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
                            SrcMgr::CharacteristicKind FileType);
+  virtual void InclusionDirective(SourceLocation HashLoc,
+                                  const Token &IncludeTok,
+                                  llvm::StringRef FileName,
+                                  bool IsAngled,
+                                  const FileEntry *File,
+                                  SourceLocation EndLoc,
+                                  llvm::StringRef SearchPath,
+                                  llvm::StringRef RelativePath);
 
   virtual void EndOfMainFile() {
     OutputDependencyFile();
@@ -73,6 +85,16 @@
     return;
   }
 
+  // Disable the "file not found" diagnostic if the -MG option was given.
+  // FIXME: Ideally this would live in the driver, but we don't have the ability
+  // to remap individual diagnostics there without creating a DiagGroup, in
+  // which case we would need to prevent the group name from showing up in
+  // diagnostics.
+  if (Opts.AddMissingHeaderDeps) {
+    PP.getDiagnostics().setDiagnosticMapping(diag::warn_pp_file_not_found,
+                                            diag::MAP_IGNORE, SourceLocation());
+  }
+
   PP.addPPCallbacks(new DependencyFileCallback(&PP, OS, Opts));
 }
 
@@ -116,7 +138,22 @@
       Filename = Filename.substr(1);
   }
     
+  AddFilename(Filename);
+}
 
+void DependencyFileCallback::InclusionDirective(SourceLocation HashLoc,
+                                                const Token &IncludeTok,
+                                                llvm::StringRef FileName,
+                                                bool IsAngled,
+                                                const FileEntry *File,
+                                                SourceLocation EndLoc,
+                                                llvm::StringRef SearchPath,
+                                                llvm::StringRef RelativePath) {
+  if (AddMissingHeaderDeps && !File)
+    AddFilename(FileName);
+}
+
+void DependencyFileCallback::AddFilename(llvm::StringRef Filename) {
   if (FilesSet.insert(Filename))
     Files.push_back(Filename);
 }