]> granicus.if.org Git - clang/commitdiff
Unify DependencyFileGenerator class and DependencyCollector interface (NFCI)
authorAlex Lorenz <arphaman@gmail.com>
Wed, 19 Jun 2019 17:07:36 +0000 (17:07 +0000)
committerAlex Lorenz <arphaman@gmail.com>
Wed, 19 Jun 2019 17:07:36 +0000 (17:07 +0000)
Make DependencyFileGenerator a DependencyCollector as it was intended when
DependencyCollector was introduced. The missing PPCallbacks overrides are added to
the DependencyCollector as well.

This change will allow clang-scan-deps to access the produced dependencies without
writing them out to .d files to disk, so that it will be able collate them and
report them to the user.

Differential Revision: https://reviews.llvm.org/D63290

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

include/clang/Frontend/CompilerInstance.h
include/clang/Frontend/Utils.h
lib/Frontend/CompilerInstance.cpp
lib/Frontend/DependencyFile.cpp

index 2eb1349f49c76142ebd8a81078b5cba0ee44293f..eb49c53ff40b785577ceeb7a5ad5ce297b96cf2c 100644 (file)
@@ -124,9 +124,6 @@ class CompilerInstance : public ModuleLoader {
   /// The module provider.
   std::shared_ptr<PCHContainerOperations> ThePCHContainerOperations;
 
-  /// The dependency file generator.
-  std::unique_ptr<DependencyFileGenerator> TheDependencyFileGenerator;
-
   std::vector<std::shared_ptr<DependencyCollector>> DependencyCollectors;
 
   /// The set of top-level modules that has already been loaded,
@@ -661,7 +658,6 @@ public:
       InMemoryModuleCache &ModuleCache, ASTContext &Context,
       const PCHContainerReader &PCHContainerRdr,
       ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
-      DependencyFileGenerator *DependencyFile,
       ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
       void *DeserializationListener, bool OwnDeserializationListener,
       bool Preamble, bool UseGlobalModuleIndex);
index 124d4a9933077ca91b0edfc901fcf4c568d26e26..951d51bbc15f42ee5f28f1b748c0ac37601c8ef2 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/LLVM.h"
+#include "clang/Frontend/DependencyOutputOptions.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/StringMap.h"
@@ -46,7 +47,6 @@ namespace clang {
 class ASTReader;
 class CompilerInstance;
 class CompilerInvocation;
-class DependencyOutputOptions;
 class DiagnosticsEngine;
 class ExternalSemaSource;
 class FrontendOptions;
@@ -77,8 +77,7 @@ void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS,
 /// An interface for collecting the dependencies of a compilation. Users should
 /// use \c attachToPreprocessor and \c attachToASTReader to get all of the
 /// dependencies.
-/// FIXME: Migrate DependencyFileGen and DependencyGraphGen to use this
-/// interface.
+/// FIXME: Migrate DependencyGraphGen to use this interface.
 class DependencyCollector {
 public:
   virtual ~DependencyCollector();
@@ -95,7 +94,7 @@ public:
                              bool IsSystem, bool IsModuleFile, bool IsMissing);
 
   /// Called when the end of the main file is reached.
-  virtual void finishedMainFile() {}
+  virtual void finishedMainFile(DiagnosticsEngine &Diags) {}
 
   /// Return true if system files should be passed to sawDependency().
   virtual bool needSystemDependencies() { return false; }
@@ -106,25 +105,45 @@ public:
   void maybeAddDependency(StringRef Filename, bool FromModule, bool IsSystem,
                           bool IsModuleFile, bool IsMissing);
 
+protected:
+  /// Return true if the filename was added to the list of dependencies, false
+  /// otherwise.
+  bool addDependency(StringRef Filename);
+
 private:
   llvm::StringSet<> Seen;
   std::vector<std::string> Dependencies;
 };
 
-/// Builds a depdenency file when attached to a Preprocessor (for includes) and
+/// Builds a dependency file when attached to a Preprocessor (for includes) and
 /// ASTReader (for module imports), and writes it out at the end of processing
 /// a source file.  Users should attach to the ast reader whenever a module is
 /// loaded.
-class DependencyFileGenerator {
-  void *Impl; // Opaque implementation
+class DependencyFileGenerator : public DependencyCollector {
+public:
+  DependencyFileGenerator(const DependencyOutputOptions &Opts);
 
-  DependencyFileGenerator(void *Impl);
+  void attachToPreprocessor(Preprocessor &PP) override;
 
-public:
-  static DependencyFileGenerator *CreateAndAttachToPreprocessor(
-    Preprocessor &PP, const DependencyOutputOptions &Opts);
+  void finishedMainFile(DiagnosticsEngine &Diags) override;
 
-  void AttachToASTReader(ASTReader &R);
+  bool needSystemDependencies() final override { return IncludeSystemHeaders; }
+
+  bool sawDependency(StringRef Filename, bool FromModule, bool IsSystem,
+                     bool IsModuleFile, bool IsMissing) final override;
+
+private:
+  void outputDependencyFile(DiagnosticsEngine &Diags);
+
+  std::string OutputFile;
+  std::vector<std::string> Targets;
+  bool IncludeSystemHeaders;
+  bool PhonyTarget;
+  bool AddMissingHeaderDeps;
+  bool SeenMissingHeader;
+  bool IncludeModuleFiles;
+  DependencyOutputFormat OutputFormat;
+  unsigned InputFileIndex;
 };
 
 /// Collects the dependencies for imported modules into a directory.  Users
index fd33b85b31d3f9cd3a9b0890d2319949bc6da12d..9cbc9ed1f7928644514cb8d2d12e10403eeb8c1d 100644 (file)
@@ -415,8 +415,7 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
   // Handle generating dependencies, if requested.
   const DependencyOutputOptions &DepOpts = getDependencyOutputOpts();
   if (!DepOpts.OutputFile.empty())
-    TheDependencyFileGenerator.reset(
-        DependencyFileGenerator::CreateAndAttachToPreprocessor(*PP, DepOpts));
+    addDependencyCollector(std::make_shared<DependencyFileGenerator>(DepOpts));
   if (!DepOpts.DOTOutputFile.empty())
     AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile,
                              getHeaderSearchOpts().Sysroot);
@@ -490,9 +489,9 @@ void CompilerInstance::createPCHExternalASTSource(
       Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation,
       AllowPCHWithCompilerErrors, getPreprocessor(), getModuleCache(),
       getASTContext(), getPCHContainerReader(),
-      getFrontendOpts().ModuleFileExtensions, TheDependencyFileGenerator.get(),
-      DependencyCollectors, DeserializationListener, OwnDeserializationListener,
-      Preamble, getFrontendOpts().UseGlobalModuleIndex);
+      getFrontendOpts().ModuleFileExtensions, DependencyCollectors,
+      DeserializationListener, OwnDeserializationListener, Preamble,
+      getFrontendOpts().UseGlobalModuleIndex);
 }
 
 IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
@@ -501,7 +500,6 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
     InMemoryModuleCache &ModuleCache, ASTContext &Context,
     const PCHContainerReader &PCHContainerRdr,
     ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
-    DependencyFileGenerator *DependencyFile,
     ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
     void *DeserializationListener, bool OwnDeserializationListener,
     bool Preamble, bool UseGlobalModuleIndex) {
@@ -521,8 +519,6 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
       static_cast<ASTDeserializationListener *>(DeserializationListener),
       /*TakeOwnership=*/OwnDeserializationListener);
 
-  if (DependencyFile)
-    DependencyFile->AttachToASTReader(*Reader);
   for (auto &Listener : DependencyCollectors)
     Listener->attachToASTReader(*Reader);
 
@@ -1492,8 +1488,6 @@ void CompilerInstance::createModuleManager() {
     if (hasASTConsumer())
       ModuleManager->StartTranslationUnit(&getASTConsumer());
 
-    if (TheDependencyFileGenerator)
-      TheDependencyFileGenerator->AttachToASTReader(*ModuleManager);
     for (auto &Listener : DependencyCollectors)
       Listener->attachToASTReader(*ModuleManager);
   }
index 363aff76f0224281ba544a52f7f494264c619e5a..b52e25bb0eb1ce30aae2adf718b2f19123bcafa6 100644 (file)
@@ -32,8 +32,10 @@ namespace {
 struct DepCollectorPPCallbacks : public PPCallbacks {
   DependencyCollector &DepCollector;
   SourceManager &SM;
-  DepCollectorPPCallbacks(DependencyCollector &L, SourceManager &SM)
-      : DepCollector(L), SM(SM) { }
+  DiagnosticsEngine &Diags;
+  DepCollectorPPCallbacks(DependencyCollector &L, SourceManager &SM,
+                          DiagnosticsEngine &Diags)
+      : DepCollector(L), SM(SM), Diags(Diags) {}
 
   void FileChanged(SourceLocation Loc, FileChangeReason Reason,
                    SrcMgr::CharacteristicKind FileType,
@@ -57,6 +59,16 @@ struct DepCollectorPPCallbacks : public PPCallbacks {
                                     /*IsModuleFile*/false, /*IsMissing*/false);
   }
 
+  void FileSkipped(const FileEntry &SkippedFile, const Token &FilenameTok,
+                   SrcMgr::CharacteristicKind FileType) override {
+    StringRef Filename =
+        llvm::sys::path::remove_leading_dotslash(SkippedFile.getName());
+    DepCollector.maybeAddDependency(Filename, /*FromModule=*/false,
+                                    /*IsSystem=*/isSystem(FileType),
+                                    /*IsModuleFile=*/false,
+                                    /*IsMissing=*/false);
+  }
+
   void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
                           StringRef FileName, bool IsAngled,
                           CharSourceRange FilenameRange, const FileEntry *File,
@@ -70,9 +82,20 @@ struct DepCollectorPPCallbacks : public PPCallbacks {
     // Files that actually exist are handled by FileChanged.
   }
 
-  void EndOfMainFile() override {
-    DepCollector.finishedMainFile();
+  void HasInclude(SourceLocation Loc, StringRef SpelledFilename, bool IsAngled,
+                  const FileEntry *File,
+                  SrcMgr::CharacteristicKind FileType) override {
+    if (!File)
+      return;
+    StringRef Filename =
+        llvm::sys::path::remove_leading_dotslash(File->getName());
+    DepCollector.maybeAddDependency(Filename, /*FromModule=*/false,
+                                    /*IsSystem=*/isSystem(FileType),
+                                    /*IsModuleFile=*/false,
+                                    /*IsMissing=*/false);
   }
+
+  void EndOfMainFile() override { DepCollector.finishedMainFile(Diags); }
 };
 
 struct DepCollectorMMCallbacks : public ModuleMapCallbacks {
@@ -117,9 +140,16 @@ struct DepCollectorASTListener : public ASTReaderListener {
 void DependencyCollector::maybeAddDependency(StringRef Filename, bool FromModule,
                                             bool IsSystem, bool IsModuleFile,
                                             bool IsMissing) {
-  if (Seen.insert(Filename).second &&
-      sawDependency(Filename, FromModule, IsSystem, IsModuleFile, IsMissing))
+  if (sawDependency(Filename, FromModule, IsSystem, IsModuleFile, IsMissing))
+    addDependency(Filename);
+}
+
+bool DependencyCollector::addDependency(StringRef Filename) {
+  if (Seen.insert(Filename).second) {
     Dependencies.push_back(Filename);
+    return true;
+  }
+  return false;
 }
 
 static bool isSpecialFilename(StringRef Filename) {
@@ -138,8 +168,8 @@ bool DependencyCollector::sawDependency(StringRef Filename, bool FromModule,
 
 DependencyCollector::~DependencyCollector() { }
 void DependencyCollector::attachToPreprocessor(Preprocessor &PP) {
-  PP.addPPCallbacks(
-      llvm::make_unique<DepCollectorPPCallbacks>(*this, PP.getSourceManager()));
+  PP.addPPCallbacks(llvm::make_unique<DepCollectorPPCallbacks>(
+      *this, PP.getSourceManager(), PP.getDiagnostics()));
   PP.getHeaderSearchInfo().getModuleMap().addModuleMapCallbacks(
       llvm::make_unique<DepCollectorMMCallbacks>(*this));
 }
@@ -147,206 +177,57 @@ void DependencyCollector::attachToASTReader(ASTReader &R) {
   R.addListener(llvm::make_unique<DepCollectorASTListener>(*this));
 }
 
-namespace {
-/// Private implementation for DependencyFileGenerator
-class DFGImpl : public PPCallbacks {
-  std::vector<std::string> Files;
-  llvm::StringSet<> FilesSet;
-  const Preprocessor *PP;
-  std::string OutputFile;
-  std::vector<std::string> Targets;
-  bool IncludeSystemHeaders;
-  bool PhonyTarget;
-  bool AddMissingHeaderDeps;
-  bool SeenMissingHeader;
-  bool IncludeModuleFiles;
-  DependencyOutputFormat OutputFormat;
-  unsigned InputFileIndex;
-
-private:
-  bool FileMatchesDepCriteria(const char *Filename,
-                              SrcMgr::CharacteristicKind FileType);
-  void OutputDependencyFile();
-
-public:
-  DFGImpl(const Preprocessor *_PP, const DependencyOutputOptions &Opts)
-    : PP(_PP), OutputFile(Opts.OutputFile), Targets(Opts.Targets),
+DependencyFileGenerator::DependencyFileGenerator(
+    const DependencyOutputOptions &Opts)
+    : OutputFile(Opts.OutputFile), Targets(Opts.Targets),
       IncludeSystemHeaders(Opts.IncludeSystemHeaders),
       PhonyTarget(Opts.UsePhonyTargets),
-      AddMissingHeaderDeps(Opts.AddMissingHeaderDeps),
-      SeenMissingHeader(false),
+      AddMissingHeaderDeps(Opts.AddMissingHeaderDeps), SeenMissingHeader(false),
       IncludeModuleFiles(Opts.IncludeModuleFiles),
-      OutputFormat(Opts.OutputFormat),
-      InputFileIndex(0) {
-    for (const auto &ExtraDep : Opts.ExtraDeps) {
-      if (AddFilename(ExtraDep))
-        ++InputFileIndex;
-    }
-  }
-
-  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
-                   SrcMgr::CharacteristicKind FileType,
-                   FileID PrevFID) override;
-
-  void FileSkipped(const FileEntry &SkippedFile, const Token &FilenameTok,
-                   SrcMgr::CharacteristicKind FileType) override;
-
-  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
-                          StringRef FileName, bool IsAngled,
-                          CharSourceRange FilenameRange, const FileEntry *File,
-                          StringRef SearchPath, StringRef RelativePath,
-                          const Module *Imported,
-                          SrcMgr::CharacteristicKind FileType) override;
-
-  void HasInclude(SourceLocation Loc, StringRef SpelledFilename, bool IsAngled,
-                  const FileEntry *File,
-                  SrcMgr::CharacteristicKind FileType) override;
-
-  void EndOfMainFile() override {
-    OutputDependencyFile();
-  }
-
-  bool AddFilename(StringRef Filename);
-  bool includeSystemHeaders() const { return IncludeSystemHeaders; }
-  bool includeModuleFiles() const { return IncludeModuleFiles; }
-};
-
-class DFGMMCallback : public ModuleMapCallbacks {
-  DFGImpl &Parent;
-public:
-  DFGMMCallback(DFGImpl &Parent) : Parent(Parent) {}
-  void moduleMapFileRead(SourceLocation Loc, const FileEntry &Entry,
-                         bool IsSystem) override {
-    if (!IsSystem || Parent.includeSystemHeaders())
-      Parent.AddFilename(Entry.getName());
-  }
-};
-
-class DFGASTReaderListener : public ASTReaderListener {
-  DFGImpl &Parent;
-public:
-  DFGASTReaderListener(DFGImpl &Parent)
-  : Parent(Parent) { }
-  bool needsInputFileVisitation() override { return true; }
-  bool needsSystemInputFileVisitation() override {
-    return Parent.includeSystemHeaders();
+      OutputFormat(Opts.OutputFormat), InputFileIndex(0) {
+  for (const auto &ExtraDep : Opts.ExtraDeps) {
+    if (addDependency(ExtraDep))
+      ++InputFileIndex;
   }
-  void visitModuleFile(StringRef Filename,
-                       serialization::ModuleKind Kind) override;
-  bool visitInputFile(StringRef Filename, bool isSystem,
-                      bool isOverridden, bool isExplicitModule) override;
-};
 }
 
-DependencyFileGenerator::DependencyFileGenerator(void *Impl)
-: Impl(Impl) { }
-
-DependencyFileGenerator *DependencyFileGenerator::CreateAndAttachToPreprocessor(
-    clang::Preprocessor &PP, const clang::DependencyOutputOptions &Opts) {
-
-  if (Opts.Targets.empty()) {
+void DependencyFileGenerator::attachToPreprocessor(Preprocessor &PP) {
+  if (Targets.empty()) {
     PP.getDiagnostics().Report(diag::err_fe_dependency_file_requires_MT);
-    return nullptr;
+    return;
   }
 
   // Disable the "file not found" diagnostic if the -MG option was given.
-  if (Opts.AddMissingHeaderDeps)
+  if (AddMissingHeaderDeps)
     PP.SetSuppressIncludeNotFoundError(true);
 
-  DFGImpl *Callback = new DFGImpl(&PP, Opts);
-  PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callback));
-  PP.getHeaderSearchInfo().getModuleMap().addModuleMapCallbacks(
-      llvm::make_unique<DFGMMCallback>(*Callback));
-  return new DependencyFileGenerator(Callback);
+  DependencyCollector::attachToPreprocessor(PP);
 }
 
-void DependencyFileGenerator::AttachToASTReader(ASTReader &R) {
-  DFGImpl *I = reinterpret_cast<DFGImpl *>(Impl);
-  assert(I && "missing implementation");
-  R.addListener(llvm::make_unique<DFGASTReaderListener>(*I));
-}
+bool DependencyFileGenerator::sawDependency(StringRef Filename, bool FromModule,
+                                            bool IsSystem, bool IsModuleFile,
+                                            bool IsMissing) {
+  if (IsMissing) {
+    // Handle the case of missing file from an inclusion directive.
+    if (AddMissingHeaderDeps)
+      return true;
+    SeenMissingHeader = true;
+    return false;
+  }
+  if (IsModuleFile && !IncludeModuleFiles)
+    return false;
 
-/// FileMatchesDepCriteria - Determine whether the given Filename should be
-/// considered as a dependency.
-bool DFGImpl::FileMatchesDepCriteria(const char *Filename,
-                                     SrcMgr::CharacteristicKind FileType) {
   if (isSpecialFilename(Filename))
     return false;
 
   if (IncludeSystemHeaders)
     return true;
 
-  return !isSystem(FileType);
-}
-
-void DFGImpl::FileChanged(SourceLocation Loc,
-                          FileChangeReason Reason,
-                          SrcMgr::CharacteristicKind FileType,
-                          FileID PrevFID) {
-  if (Reason != PPCallbacks::EnterFile)
-    return;
-
-  // Dependency generation really does want to go all the way to the
-  // file entry for a source location to find out what is depended on.
-  // We do not want #line markers to affect dependency generation!
-  SourceManager &SM = PP->getSourceManager();
-
-  const FileEntry *FE =
-    SM.getFileEntryForID(SM.getFileID(SM.getExpansionLoc(Loc)));
-  if (!FE) return;
-
-  StringRef Filename = FE->getName();
-  if (!FileMatchesDepCriteria(Filename.data(), FileType))
-    return;
-
-  AddFilename(llvm::sys::path::remove_leading_dotslash(Filename));
+  return !IsSystem;
 }
 
-void DFGImpl::FileSkipped(const FileEntry &SkippedFile,
-                          const Token &FilenameTok,
-                          SrcMgr::CharacteristicKind FileType) {
-  StringRef Filename = SkippedFile.getName();
-  if (!FileMatchesDepCriteria(Filename.data(), FileType))
-    return;
-
-  AddFilename(llvm::sys::path::remove_leading_dotslash(Filename));
-}
-
-void DFGImpl::InclusionDirective(SourceLocation HashLoc,
-                                 const Token &IncludeTok,
-                                 StringRef FileName,
-                                 bool IsAngled,
-                                 CharSourceRange FilenameRange,
-                                 const FileEntry *File,
-                                 StringRef SearchPath,
-                                 StringRef RelativePath,
-                                 const Module *Imported,
-                                 SrcMgr::CharacteristicKind FileType) {
-  if (!File) {
-    if (AddMissingHeaderDeps)
-      AddFilename(FileName);
-    else
-      SeenMissingHeader = true;
-  }
-}
-
-void DFGImpl::HasInclude(SourceLocation Loc, StringRef SpelledFilename,
-                         bool IsAngled, const FileEntry *File,
-                         SrcMgr::CharacteristicKind FileType) {
-  if (!File)
-    return;
-  StringRef Filename = File->getName();
-  if (!FileMatchesDepCriteria(Filename.data(), FileType))
-    return;
-  AddFilename(llvm::sys::path::remove_leading_dotslash(Filename));
-}
-
-bool DFGImpl::AddFilename(StringRef Filename) {
-  if (FilesSet.insert(Filename).second) {
-    Files.push_back(Filename);
-    return true;
-  }
-  return false;
+void DependencyFileGenerator::finishedMainFile(DiagnosticsEngine &Diags) {
+  outputDependencyFile(Diags);
 }
 
 /// Print the filename, with escaping or quoting that accommodates the three
@@ -428,7 +309,7 @@ static void PrintFilename(raw_ostream &OS, StringRef Filename,
   }
 }
 
-void DFGImpl::OutputDependencyFile() {
+void DependencyFileGenerator::outputDependencyFile(DiagnosticsEngine &Diags) {
   if (SeenMissingHeader) {
     llvm::sys::fs::remove(OutputFile);
     return;
@@ -437,8 +318,7 @@ void DFGImpl::OutputDependencyFile() {
   std::error_code EC;
   llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::F_Text);
   if (EC) {
-    PP->getDiagnostics().Report(diag::err_fe_error_opening) << OutputFile
-                                                            << EC.message();
+    Diags.Report(diag::err_fe_error_opening) << OutputFile << EC.message();
     return;
   }
 
@@ -469,6 +349,7 @@ void DFGImpl::OutputDependencyFile() {
 
   // Now add each dependency in the order it was seen, but avoiding
   // duplicates.
+  ArrayRef<std::string> Files = getDependencies();
   for (StringRef File : Files) {
     // Start a new line if this would exceed the column limit. Make
     // sure to leave space for a trailing " \" in case we need to
@@ -496,20 +377,3 @@ void DFGImpl::OutputDependencyFile() {
     }
   }
 }
-
-bool DFGASTReaderListener::visitInputFile(llvm::StringRef Filename,
-                                          bool IsSystem, bool IsOverridden,
-                                          bool IsExplicitModule) {
-  assert(!IsSystem || needsSystemInputFileVisitation());
-  if (IsOverridden || IsExplicitModule)
-    return true;
-
-  Parent.AddFilename(Filename);
-  return true;
-}
-
-void DFGASTReaderListener::visitModuleFile(llvm::StringRef Filename,
-                                           serialization::ModuleKind Kind) {
-  if (Parent.includeModuleFiles())
-    Parent.AddFilename(Filename);
-}