From 536d89fbf022784c082bd52d79c77f02f64ed8a4 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat@intel.com>
Date: Tue, 6 Aug 2024 13:18:20 -0700
Subject: [PATCH] [SYCL] Filter out the header and footer from the dependency
 output. (#14933)

`Cmake` uses dependency information generated by the use of the` -MD`
option to decide if a file needs to be rebuilt. Currently the header and
footer are not filtered out from the dependency output. This leads to
the issue that `Cmake` thinks the source file needs to always be
rebuilt.
This is a patch to fix the issue.
See https://github.com/intel/llvm/discussions/14798 for more details.
---
 clang/include/clang/Driver/Options.td                  | 2 +-
 clang/include/clang/Frontend/DependencyOutputOptions.h | 4 ++--
 clang/include/clang/Frontend/Utils.h                   | 2 +-
 clang/lib/Frontend/DependencyFile.cpp                  | 9 ++++-----
 clang/test/Frontend/Inputs/dependency.cpp              | 3 +++
 clang/test/Frontend/dependency-gen.c                   | 8 ++++++++
 6 files changed, 19 insertions(+), 9 deletions(-)
 create mode 100644 clang/test/Frontend/Inputs/dependency.cpp

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index fdca78487b0ce..4551e2ca15787 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -7696,7 +7696,7 @@ def show_includes : Flag<["--"], "show-includes">,
   HelpText<"Print cl.exe style /showIncludes to stdout">;
 def dependency_filter : Separate<["-"], "dependency-filter">,
   HelpText<"Filter dependencies with prefix from the dependency output.">,
-  MarshallingInfoString<DependencyOutputOpts<"DependencyFilter">>;
+  MarshallingInfoStringVector<DependencyOutputOpts<"DependencyFilter">>;
 
 } // let Visibility = [CC1Option]
 
diff --git a/clang/include/clang/Frontend/DependencyOutputOptions.h b/clang/include/clang/Frontend/DependencyOutputOptions.h
index db583b7e4d7bb..dca0390558cb3 100644
--- a/clang/include/clang/Frontend/DependencyOutputOptions.h
+++ b/clang/include/clang/Frontend/DependencyOutputOptions.h
@@ -87,8 +87,8 @@ class DependencyOutputOptions {
   std::string ModuleDependencyOutputDir;
 
   /// Dependency output which is prefixed with this string is filtered from
-  /// the dependency output. 
-  std::string DependencyFilter;
+  /// the dependency output.
+  std::vector<std::string> DependencyFilter;
 
 public:
   DependencyOutputOptions()
diff --git a/clang/include/clang/Frontend/Utils.h b/clang/include/clang/Frontend/Utils.h
index 4c8edaeefb517..110b008993f1b 100644
--- a/clang/include/clang/Frontend/Utils.h
+++ b/clang/include/clang/Frontend/Utils.h
@@ -121,7 +121,7 @@ class DependencyFileGenerator : public DependencyCollector {
   void outputDependencyFile(DiagnosticsEngine &Diags);
 
   std::string OutputFile;
-  std::string DependencyFilter;
+  std::vector<std::string> DependencyFilter;
   std::vector<std::string> Targets;
   bool IncludeSystemHeaders;
   bool PhonyTarget;
diff --git a/clang/lib/Frontend/DependencyFile.cpp b/clang/lib/Frontend/DependencyFile.cpp
index 5297517a4956c..5a0d44298823a 100644
--- a/clang/lib/Frontend/DependencyFile.cpp
+++ b/clang/lib/Frontend/DependencyFile.cpp
@@ -255,11 +255,10 @@ bool DependencyFileGenerator::sawDependency(StringRef Filename, bool FromModule,
   if (isSpecialFilename(Filename))
     return false;
 
-  if (DependencyFilter.size() &&
-      DependencyFilter.compare(0, DependencyFilter.size(), Filename.data(),
-                               DependencyFilter.size()) == 0)
-    // Remove dependencies that are prefixed by the Filter string.
-    return false;
+  // Remove dependencies that are prefixed by the Filter string.
+  for (const std::string &FD : DependencyFilter)
+    if (FD.compare(0, FD.size(), Filename.data(), FD.size()) == 0)
+      return false;
 
   if (IncludeSystemHeaders)
     return true;
diff --git a/clang/test/Frontend/Inputs/dependency.cpp b/clang/test/Frontend/Inputs/dependency.cpp
new file mode 100644
index 0000000000000..3e1b41306e1cf
--- /dev/null
+++ b/clang/test/Frontend/Inputs/dependency.cpp
@@ -0,0 +1,3 @@
+int dep() {
+  return 0;
+}
diff --git a/clang/test/Frontend/dependency-gen.c b/clang/test/Frontend/dependency-gen.c
index b0a3ec174ebdb..664a86a345ebb 100644
--- a/clang/test/Frontend/dependency-gen.c
+++ b/clang/test/Frontend/dependency-gen.c
@@ -47,3 +47,11 @@
 // RUN: %clang -MMD -MF - %s -fsyntax-only -resource-dir=%S/Inputs/resource_dir_with_sanitizer_ignorelist -fsanitize=undefined -flto -fvisibility=hidden -I ./ | FileCheck -check-prefix=ONLY-USER-DEPS %s
 // ONLY-USER-DEPS: dependency-gen.o:
 // NOT-ONLY-USER-DEPS: ubsan_ignorelist.txt
+
+// RUN: %clang -c -x c++ -fsycl \
+// RUN: -MD -MF - %S/Inputs/dependency.cpp | FileCheck -check-prefix=FILTER %s
+
+// FILTER: dependency.o:
+// FILTER: {{.*}}dependency.cpp
+// FILTER: dependency.o:
+// FILTER: {{.*}}dependency.cpp