[Modules] Emit the module file paths as dependencies of the PCH when we are building one.

This is because the PCH is tied to the module files, if one of the module files changes or gets removed
the build system should re-build the PCH file.

rdar://16321245

llvm-svn: 203885
This commit is contained in:
Argyrios Kyrtzidis 2014-03-14 03:07:38 +00:00
parent f88731f293
commit 6d0753d42a
9 changed files with 50 additions and 1 deletions

View File

@ -223,6 +223,8 @@ def dependent_lib : Joined<["--"], "dependent-lib=">,
def sys_header_deps : Flag<["-"], "sys-header-deps">, def sys_header_deps : Flag<["-"], "sys-header-deps">,
HelpText<"Include system headers in dependency output">; HelpText<"Include system headers in dependency output">;
def module_file_deps : Flag<["-"], "module-file-deps">,
HelpText<"Include module files in dependency output">;
def header_include_file : Separate<["-"], "header-include-file">, def header_include_file : Separate<["-"], "header-include-file">,
HelpText<"Filename (or -) to write header include output to">; HelpText<"Filename (or -) to write header include output to">;
def show_includes : Flag<["--"], "show-includes">, def show_includes : Flag<["--"], "show-includes">,

View File

@ -26,6 +26,7 @@ public:
/// problems. /// problems.
unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list
unsigned PrintShowIncludes : 1; ///< Print cl.exe style /showIncludes info. unsigned PrintShowIncludes : 1; ///< Print cl.exe style /showIncludes info.
unsigned IncludeModuleFiles : 1; ///< Include module file dependencies.
/// The file to write dependency output to. /// The file to write dependency output to.
std::string OutputFile; std::string OutputFile;
@ -50,6 +51,7 @@ public:
UsePhonyTargets = 0; UsePhonyTargets = 0;
AddMissingHeaderDeps = 0; AddMissingHeaderDeps = 0;
PrintShowIncludes = 0; PrintShowIncludes = 0;
IncludeModuleFiles = 0;
} }
}; };

View File

@ -171,6 +171,9 @@ public:
virtual void ReadCounter(const serialization::ModuleFile &M, virtual void ReadCounter(const serialization::ModuleFile &M,
unsigned Value) {} unsigned Value) {}
/// This is called for each AST file loaded.
virtual void visitModuleFile(StringRef Filename) {}
/// \brief Returns true if this \c ASTReaderListener wants to receive the /// \brief Returns true if this \c ASTReaderListener wants to receive the
/// input files of the AST file via \c visitInputFile, false otherwise. /// input files of the AST file via \c visitInputFile, false otherwise.
virtual bool needsInputFileVisitation() { return false; } virtual bool needsInputFileVisitation() { return false; }
@ -217,6 +220,7 @@ public:
void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override; void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override;
bool needsInputFileVisitation() override; bool needsInputFileVisitation() override;
bool needsSystemInputFileVisitation() override; bool needsSystemInputFileVisitation() override;
void visitModuleFile(StringRef Filename) override;
bool visitInputFile(StringRef Filename, bool isSystem, bool visitInputFile(StringRef Filename, bool isSystem,
bool isOverridden) override; bool isOverridden) override;
}; };

View File

@ -295,6 +295,9 @@ void Clang::AddPreprocessingOptions(Compilation &C,
if (A->getOption().matches(options::OPT_M) || if (A->getOption().matches(options::OPT_M) ||
A->getOption().matches(options::OPT_MD)) A->getOption().matches(options::OPT_MD))
CmdArgs.push_back("-sys-header-deps"); CmdArgs.push_back("-sys-header-deps");
if (isa<PrecompileJobAction>(JA))
CmdArgs.push_back("-module-file-deps");
} }
if (Args.hasArg(options::OPT_MG)) { if (Args.hasArg(options::OPT_MG)) {

View File

@ -528,6 +528,7 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
Opts.OutputFile = Args.getLastArgValue(OPT_dependency_file); Opts.OutputFile = Args.getLastArgValue(OPT_dependency_file);
Opts.Targets = Args.getAllArgValues(OPT_MT); Opts.Targets = Args.getAllArgValues(OPT_MT);
Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps); Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps);
Opts.IncludeModuleFiles = Args.hasArg(OPT_module_file_deps);
Opts.UsePhonyTargets = Args.hasArg(OPT_MP); Opts.UsePhonyTargets = Args.hasArg(OPT_MP);
Opts.ShowHeaderIncludes = Args.hasArg(OPT_H); Opts.ShowHeaderIncludes = Args.hasArg(OPT_H);
Opts.HeaderIncludeOutputFile = Args.getLastArgValue(OPT_header_include_file); Opts.HeaderIncludeOutputFile = Args.getLastArgValue(OPT_header_include_file);

View File

@ -40,6 +40,7 @@ class DFGImpl : public PPCallbacks {
bool PhonyTarget; bool PhonyTarget;
bool AddMissingHeaderDeps; bool AddMissingHeaderDeps;
bool SeenMissingHeader; bool SeenMissingHeader;
bool IncludeModuleFiles;
private: private:
bool FileMatchesDepCriteria(const char *Filename, bool FileMatchesDepCriteria(const char *Filename,
SrcMgr::CharacteristicKind FileType); SrcMgr::CharacteristicKind FileType);
@ -51,7 +52,8 @@ public:
IncludeSystemHeaders(Opts.IncludeSystemHeaders), IncludeSystemHeaders(Opts.IncludeSystemHeaders),
PhonyTarget(Opts.UsePhonyTargets), PhonyTarget(Opts.UsePhonyTargets),
AddMissingHeaderDeps(Opts.AddMissingHeaderDeps), AddMissingHeaderDeps(Opts.AddMissingHeaderDeps),
SeenMissingHeader(false) {} SeenMissingHeader(false),
IncludeModuleFiles(Opts.IncludeModuleFiles) {}
void FileChanged(SourceLocation Loc, FileChangeReason Reason, void FileChanged(SourceLocation Loc, FileChangeReason Reason,
SrcMgr::CharacteristicKind FileType, SrcMgr::CharacteristicKind FileType,
@ -68,6 +70,7 @@ public:
void AddFilename(StringRef Filename); void AddFilename(StringRef Filename);
bool includeSystemHeaders() const { return IncludeSystemHeaders; } bool includeSystemHeaders() const { return IncludeSystemHeaders; }
bool includeModuleFiles() const { return IncludeModuleFiles; }
}; };
class DFGASTReaderListener : public ASTReaderListener { class DFGASTReaderListener : public ASTReaderListener {
@ -79,6 +82,7 @@ public:
bool needsSystemInputFileVisitation() override { bool needsSystemInputFileVisitation() override {
return Parent.includeSystemHeaders(); return Parent.includeSystemHeaders();
} }
void visitModuleFile(StringRef Filename) override;
bool visitInputFile(StringRef Filename, bool isSystem, bool visitInputFile(StringRef Filename, bool isSystem,
bool isOverridden) override; bool isOverridden) override;
}; };
@ -268,3 +272,7 @@ bool DFGASTReaderListener::visitInputFile(llvm::StringRef Filename,
return true; return true;
} }
void DFGASTReaderListener::visitModuleFile(llvm::StringRef Filename) {
if (Parent.includeModuleFiles())
Parent.AddFilename(Filename);
}

View File

@ -118,6 +118,10 @@ bool ChainedASTReaderListener::needsSystemInputFileVisitation() {
return First->needsSystemInputFileVisitation() || return First->needsSystemInputFileVisitation() ||
Second->needsSystemInputFileVisitation(); Second->needsSystemInputFileVisitation();
} }
void ChainedASTReaderListener::visitModuleFile(StringRef Filename) {
First->visitModuleFile(Filename);
Second->visitModuleFile(Filename);
}
bool ChainedASTReaderListener::visitInputFile(StringRef Filename, bool ChainedASTReaderListener::visitInputFile(StringRef Filename,
bool isSystem, bool isSystem,
bool isOverridden) { bool isOverridden) {
@ -2118,6 +2122,9 @@ ASTReader::ReadControlBlock(ModuleFile &F,
} }
} }
if (Listener)
Listener->visitModuleFile(F.FileName);
if (Listener && Listener->needsInputFileVisitation()) { if (Listener && Listener->needsInputFileVisitation()) {
unsigned N = Listener->needsSystemInputFileVisitation() ? NumInputs unsigned N = Listener->needsSystemInputFileVisitation() ? NumInputs
: NumUserInputs; : NumUserInputs;

View File

@ -0,0 +1,10 @@
// RUN: %clang -x c-header %s -o %t.pch -MMD -MT dependencies -MF %t.d -### 2> %t
// RUN: FileCheck %s -input-file=%t
// CHECK: -emit-pch
// CHECK: -dependency-file
// CHECK: -module-file-deps
// RUN: %clang -c %s -o %t -MMD -MT dependencies -MF %t.d -### 2> %t
// RUN: FileCheck %s -check-prefix=CHECK-NOPCH -input-file=%t
// CHECK-NOPCH: -dependency-file
// CHECK-NOPCH-NOT: -module-file-deps

View File

@ -0,0 +1,12 @@
// RUN: rm -rf %t-mcp
// RUN: mkdir -p %t-mcp
// RUN: %clang_cc1 -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -module-file-deps -dependency-file %t.d -MT %s.o -I %S/Inputs -fmodules -fmodules-cache-path=%t-mcp -emit-pch -o %t.pch %s
// RUN: FileCheck %s < %t.d
// CHECK: dependency-gen-pch.m.o
// CHECK-NEXT: dependency-gen-pch.m
// CHECK-NEXT: diamond_top.pcm
// CHECK-NEXT: Inputs{{.}}diamond_top.h
// CHECK-NEXT: Inputs{{.}}module.map
#import "diamond_top.h"