Index: docs/ClangCommandLineReference.rst =================================================================== --- docs/ClangCommandLineReference.rst +++ docs/ClangCommandLineReference.rst @@ -1130,6 +1130,10 @@ Use NMake/Jom format for the depfile +.. option:: -MD-filter=prefix + +Specify prefix string for dependencies which should be omitted from depfile + Dumping preprocessor state -------------------------- Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -368,6 +368,8 @@ HelpText<"Like -MD, but also implies -E and writes to stdout by default">; def MM : Flag<["-"], "MM">, Group, HelpText<"Like -MMD, but also implies -E and writes to stdout by default">; +def MD_filter : Joined<["-"], "MD-filter=">, Group, + HelpText<"Filter depfile output prefixed with string from -MMD, -MD, -MM, or -M">; def MF : JoinedOrSeparate<["-"], "MF">, Group, HelpText<"Write depfile output from -MMD, -MD, -MM, or -M to ">, MetaVarName<"">; @@ -609,6 +611,8 @@ HelpText<"Filename to write DOT-formatted header dependencies to">; def module_dependency_dir : Separate<["-"], "module-dependency-dir">, Flags<[CC1Option]>, HelpText<"Directory to dump module dependencies to">; +def dependency_filter : Separate<["-"], "dependency-filter">, Flags<[CC1Option]>, + HelpText<"Filter dependencies with prefix from the dependency output.">; def dumpmachine : Flag<["-"], "dumpmachine">; def dumpspecs : Flag<["-"], "dumpspecs">, Flags<[Unsupported]>; def dumpversion : Flag<["-"], "dumpversion">; Index: include/clang/Frontend/DependencyOutputOptions.h =================================================================== --- include/clang/Frontend/DependencyOutputOptions.h +++ include/clang/Frontend/DependencyOutputOptions.h @@ -41,6 +41,10 @@ /// The file to write dependency output to. std::string OutputFile; + /// Dependency output which is prefixed with this string is filtered + /// from the dependency output. + std::string DependencyFilter; + /// The file to write header include output to. This is orthogonal to /// ShowHeaderIncludes (-H) and will include headers mentioned in the /// predefines buffer. If the output file is "-", output will be sent to Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -1118,6 +1118,11 @@ CmdArgs.push_back("-module-file-deps"); } + if (Arg *MD_Filter = Args.getLastArg(options::OPT_MD_filter)) { + CmdArgs.push_back("-dependency-filter"); + CmdArgs.push_back(MD_Filter->getValue()); + } + if (Args.hasArg(options::OPT_MG)) { if (!A || A->getOption().matches(options::OPT_MD) || A->getOption().matches(options::OPT_MMD)) Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -1340,6 +1340,7 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts, ArgList &Args) { Opts.OutputFile = Args.getLastArgValue(OPT_dependency_file); + Opts.DependencyFilter = Args.getLastArgValue(OPT_dependency_filter); Opts.Targets = Args.getAllArgValues(OPT_MT); Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps); Opts.IncludeModuleFiles = Args.hasArg(OPT_module_file_deps); Index: lib/Frontend/DependencyFile.cpp =================================================================== --- lib/Frontend/DependencyFile.cpp +++ lib/Frontend/DependencyFile.cpp @@ -154,6 +154,7 @@ llvm::StringSet<> FilesSet; const Preprocessor *PP; std::string OutputFile; + std::string DependencyFilter; std::vector Targets; bool IncludeSystemHeaders; bool PhonyTarget; @@ -170,7 +171,8 @@ public: DFGImpl(const Preprocessor *_PP, const DependencyOutputOptions &Opts) - : PP(_PP), OutputFile(Opts.OutputFile), Targets(Opts.Targets), + : PP(_PP), OutputFile(Opts.OutputFile), + DependencyFilter(Opts.DependencyFilter), Targets(Opts.Targets), IncludeSystemHeaders(Opts.IncludeSystemHeaders), PhonyTarget(Opts.UsePhonyTargets), AddMissingHeaderDeps(Opts.AddMissingHeaderDeps), @@ -273,6 +275,12 @@ if (isSpecialFilename(Filename)) return false; + if (DependencyFilter.size() && + DependencyFilter.compare(0, DependencyFilter.size(), Filename, + DependencyFilter.size()) == 0) + // Remove dependencies that are prefixed by the Filter string. + return false; + if (IncludeSystemHeaders) return true; Index: test/Frontend/dependency-gen.c =================================================================== --- test/Frontend/dependency-gen.c +++ test/Frontend/dependency-gen.c @@ -5,6 +5,11 @@ // RUN: cd %t.dir // RUN: %clang -MD -MF - %s -fsyntax-only -I a/b | FileCheck -check-prefix=CHECK-ONE %s // CHECK-ONE: {{ }}a{{[/\\]}}b{{[/\\]}}x.h +// RUN: %clang -MD -MF - %s -fsyntax-only -I a/b -MD-filter="a/b" | FileCheck -check-prefix=CHECK-FILTER %s +// CHECK-FILTER-NOT: {{ }}a{{[/\\]}}b{{[/\\]}}x.h +// RUN: %clang -MD -MF - %s -fsyntax-only -I a/b -MD-filter="a/b" | FileCheck -check-prefix=CHECK-WS %s +// RUN: %clang -MD -MF - %s -fsyntax-only -I a/b -MD-filter="fail" | FileCheck -check-prefix=CHECK-ONE %s +// CHECK-WS: {{^ *$}} // PR8974 (-include flag) // RUN: %clang -MD -MF - %s -fsyntax-only -include a/b/x.h -DINCLUDE_FLAG_TEST | FileCheck -check-prefix=CHECK-TWO %s