def sys_header_deps : Flag<["-"], "sys-header-deps">,
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">,
HelpText<"Filename (or -) to write header include output to">;
def show_includes : Flag<["--"], "show-includes">,
/// problems.
unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list
unsigned PrintShowIncludes : 1; ///< Print cl.exe style /showIncludes info.
+ unsigned IncludeModuleFiles : 1; ///< Include module file dependencies.
/// The file to write dependency output to.
std::string OutputFile;
UsePhonyTargets = 0;
AddMissingHeaderDeps = 0;
PrintShowIncludes = 0;
+ IncludeModuleFiles = 0;
}
};
virtual void ReadCounter(const serialization::ModuleFile &M,
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
/// input files of the AST file via \c visitInputFile, false otherwise.
virtual bool needsInputFileVisitation() { return false; }
void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override;
bool needsInputFileVisitation() override;
bool needsSystemInputFileVisitation() override;
+ void visitModuleFile(StringRef Filename) override;
bool visitInputFile(StringRef Filename, bool isSystem,
bool isOverridden) override;
};
if (A->getOption().matches(options::OPT_M) ||
A->getOption().matches(options::OPT_MD))
CmdArgs.push_back("-sys-header-deps");
+
+ if (isa<PrecompileJobAction>(JA))
+ CmdArgs.push_back("-module-file-deps");
}
if (Args.hasArg(options::OPT_MG)) {
Opts.OutputFile = Args.getLastArgValue(OPT_dependency_file);
Opts.Targets = Args.getAllArgValues(OPT_MT);
Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps);
+ Opts.IncludeModuleFiles = Args.hasArg(OPT_module_file_deps);
Opts.UsePhonyTargets = Args.hasArg(OPT_MP);
Opts.ShowHeaderIncludes = Args.hasArg(OPT_H);
Opts.HeaderIncludeOutputFile = Args.getLastArgValue(OPT_header_include_file);
bool PhonyTarget;
bool AddMissingHeaderDeps;
bool SeenMissingHeader;
+ bool IncludeModuleFiles;
private:
bool FileMatchesDepCriteria(const char *Filename,
SrcMgr::CharacteristicKind FileType);
IncludeSystemHeaders(Opts.IncludeSystemHeaders),
PhonyTarget(Opts.UsePhonyTargets),
AddMissingHeaderDeps(Opts.AddMissingHeaderDeps),
- SeenMissingHeader(false) {}
+ SeenMissingHeader(false),
+ IncludeModuleFiles(Opts.IncludeModuleFiles) {}
void FileChanged(SourceLocation Loc, FileChangeReason Reason,
SrcMgr::CharacteristicKind FileType,
void AddFilename(StringRef Filename);
bool includeSystemHeaders() const { return IncludeSystemHeaders; }
+ bool includeModuleFiles() const { return IncludeModuleFiles; }
};
class DFGASTReaderListener : public ASTReaderListener {
bool needsSystemInputFileVisitation() override {
return Parent.includeSystemHeaders();
}
+ void visitModuleFile(StringRef Filename) override;
bool visitInputFile(StringRef Filename, bool isSystem,
bool isOverridden) override;
};
return true;
}
+void DFGASTReaderListener::visitModuleFile(llvm::StringRef Filename) {
+ if (Parent.includeModuleFiles())
+ Parent.AddFilename(Filename);
+}
return First->needsSystemInputFileVisitation() ||
Second->needsSystemInputFileVisitation();
}
+void ChainedASTReaderListener::visitModuleFile(StringRef Filename) {
+ First->visitModuleFile(Filename);
+ Second->visitModuleFile(Filename);
+}
bool ChainedASTReaderListener::visitInputFile(StringRef Filename,
bool isSystem,
bool isOverridden) {
}
}
+ if (Listener)
+ Listener->visitModuleFile(F.FileName);
+
if (Listener && Listener->needsInputFileVisitation()) {
unsigned N = Listener->needsSystemInputFileVisitation() ? NumInputs
: NumUserInputs;
--- /dev/null
+// 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
--- /dev/null
+// 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"