[clang] 6052a8a - [clang] In DependencyCollector on Windows, ignore case and separators when discarding duplicate dependency file paths.

Sylvain Audi via cfe-commits cfe-commits at lists.llvm.org
Mon May 17 07:34:12 PDT 2021


Author: Sylvain Audi
Date: 2021-05-17T10:32:52-04:00
New Revision: 6052a8a53559d667321637f7159353ab724a1141

URL: https://github.com/llvm/llvm-project/commit/6052a8a53559d667321637f7159353ab724a1141
DIFF: https://github.com/llvm/llvm-project/commit/6052a8a53559d667321637f7159353ab724a1141.diff

LOG: [clang] In DependencyCollector on Windows, ignore case and separators when discarding duplicate dependency file paths.

This patch removes duplicates also encountered in the output of clang-scan-deps when one same header file is encountered with different casing and/or different separators ('/' vs '\').

The case of separators can appear when the same file is included externally by
 `#include <folder/file.h>`

whereas a file from the same folder does
 `#include "file.h"`

Under Windows, clang computes the paths using '/' from the include directive, the `\` from the -I options, and the concatenations use the native `\`, leading to internal paths containing a mix of both separators.

Differential Revision: https://reviews.llvm.org/D102339

Added: 
    clang/test/Frontend/dependency-gen-windows-duplicates.c

Modified: 
    clang/lib/Frontend/DependencyFile.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Frontend/DependencyFile.cpp b/clang/lib/Frontend/DependencyFile.cpp
index ccc7ed9d8d49..288827374106 100644
--- a/clang/lib/Frontend/DependencyFile.cpp
+++ b/clang/lib/Frontend/DependencyFile.cpp
@@ -141,7 +141,18 @@ void DependencyCollector::maybeAddDependency(StringRef Filename,
 }
 
 bool DependencyCollector::addDependency(StringRef Filename) {
-  if (Seen.insert(Filename).second) {
+  StringRef SearchPath;
+#ifdef _WIN32
+  // Make the search insensitive to case and separators.
+  llvm::SmallString<256> TmpPath = Filename;
+  llvm::sys::path::native(TmpPath);
+  std::transform(TmpPath.begin(), TmpPath.end(), TmpPath.begin(), ::tolower);
+  SearchPath = TmpPath.str();
+#else
+  SearchPath = Filename;
+#endif
+
+  if (Seen.insert(SearchPath).second) {
     Dependencies.push_back(std::string(Filename));
     return true;
   }

diff  --git a/clang/test/Frontend/dependency-gen-windows-duplicates.c b/clang/test/Frontend/dependency-gen-windows-duplicates.c
new file mode 100644
index 000000000000..abd351377dc3
--- /dev/null
+++ b/clang/test/Frontend/dependency-gen-windows-duplicates.c
@@ -0,0 +1,27 @@
+// REQUIRES: system-windows
+
+// RUN: rm -rf %t.dir
+// RUN: mkdir -p %t.dir/subdir
+// RUN: echo > %t.dir/subdir/x.h
+// RUN: cp %s %t.dir/test.c
+// RUN: cd %t.dir
+
+// RUN: %clang -MD -MF - %t.dir/test.c -fsyntax-only -I %t.dir/subdir | FileCheck %s
+// CHECK: test.o:
+// CHECK-NEXT: \test.c
+// CHECK-NEXT: \SubDir\X.h
+// File x.h must appear only once (case insensitive check).
+// CHECK-NOT: {{\\|/}}{{x|X}}.{{h|H}}
+
+// Include x.h several times, with 
diff erent casing and separators.
+// Since all paths are passed to clang as absolute, all dependencies are absolute paths.
+// We expect the output dependencies to contain only one line for file x.h
+
+// Test case sensitivity.
+#include "SubDir/X.h"
+#include "subdir/x.h"
+
+// Test separator sensitivity:
+// clang internally concatenates x.h using the Windows native separator.
+#include <x.h>
+


        


More information about the cfe-commits mailing list