summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Frontend/CompilerInstance.h4
-rw-r--r--clang/include/clang/Frontend/Utils.h43
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp14
-rw-r--r--clang/lib/Frontend/DependencyFile.cpp274
4 files changed, 104 insertions, 231 deletions
diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h
index 2eb1349f49c..eb49c53ff40 100644
--- a/clang/include/clang/Frontend/CompilerInstance.h
+++ b/clang/include/clang/Frontend/CompilerInstance.h
@@ -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);
diff --git a/clang/include/clang/Frontend/Utils.h b/clang/include/clang/Frontend/Utils.h
index 124d4a99330..951d51bbc15 100644
--- a/clang/include/clang/Frontend/Utils.h
+++ b/clang/include/clang/Frontend/Utils.h
@@ -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
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index fd33b85b31d..9cbc9ed1f79 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -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);
}
diff --git a/clang/lib/Frontend/DependencyFile.cpp b/clang/lib/Frontend/DependencyFile.cpp
index 363aff76f02..b52e25bb0eb 100644
--- a/clang/lib/Frontend/DependencyFile.cpp
+++ b/clang/lib/Frontend/DependencyFile.cpp
@@ -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);
-}
OpenPOWER on IntegriCloud