Improve VFS compatibility on Windows
authorAdrian McCarthy <amccarth@google.com>
Thu, 7 Nov 2019 18:50:33 +0000 (10:50 -0800)
committerAdrian McCarthy <amccarth@google.com>
Thu, 14 Nov 2019 16:48:47 +0000 (08:48 -0800)
Keys in a virtual file system can be in Posix or Windows form or even
a combination of the two.  Many VFS tests (and a few Clang tests) were
XFAILed on Windows because of false negatives when comparing paths.

First, we default CaseSenstive to false on Windows.  This allows
drive letters like "D:" to match "d:".  Windows filesystems are, by
default, case insensitive, so this makes sense even beyond the drive
letter.

Second, we allow slashes to match backslashes when they're used as the
root component of a path.

Both of these changes are limited to RedirectingFileSystems, so there's
little chance of affecting other path handling.

These changes allow eleven of the VFS tests to pass on Windows as well
as three other Clang tests, so they have re-enabled.

This solves the majority of PR43272.  Additional VFS test failures will
be fixed in separate patches.

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

17 files changed:
clang/test/Index/index-module-with-vfs.m
clang/test/Modules/double-quotes.m
clang/test/Modules/framework-public-includes-private.m
clang/test/VFS/external-names.c
clang/test/VFS/framework-import.m
clang/test/VFS/implicit-include.c
clang/test/VFS/include-mixed-real-and-virtual.c
clang/test/VFS/include-real-from-virtual.c
clang/test/VFS/include-virtual-from-real.c
clang/test/VFS/include.c
clang/test/VFS/incomplete-umbrella.m
clang/test/VFS/module-import.m
clang/test/VFS/real-path-found-first.m
clang/test/VFS/relative-path.c
clang/test/VFS/umbrella-framework-import-skipnonexist.m
llvm/include/llvm/Support/VirtualFileSystem.h
llvm/lib/Support/VirtualFileSystem.cpp

index a1c74cfd8de06e6fbaeec3cfd23ada5b909e08b2..46fa68dfa130885b3773a706886960b66595bb8f 100644 (file)
@@ -1,6 +1,3 @@
-// FIXME: PR43272
-// XFAIL: system-windows
-
 @import ModuleNeedsVFS;
 
 void foo() {
@@ -13,7 +10,7 @@ void foo() {
 // RUN: c-index-test -index-file %s -fmodules-cache-path=%t.cache -fmodules -F %t -I %t \
 // RUN:              -ivfsoverlay %t.yaml -Xclang -fdisable-module-hash | FileCheck %s
 
-// CHECK: [importedASTFile]: {{.*}}ModuleNeedsVFS.pcm | loc: 4:1 | name: "ModuleNeedsVFS" | isImplicit: 0
+// CHECK: [importedASTFile]: {{.*}}ModuleNeedsVFS.pcm | loc: 1:1 | name: "ModuleNeedsVFS" | isImplicit: 0
 // CHECK: [indexEntityReference]: kind: function | name: module_needs_vfs
 // CHECK: [indexEntityReference]: kind: function | name: base_module_needs_vfs
 
index bed6a48726b50d88caf225555f815f4c77400ecc..4ce712ccc6c54fca4234713d14b1da162b508f03 100644 (file)
@@ -1,6 +1,3 @@
-// FIXME: PR43272
-// XFAIL: system-windows
-
 // RUN: rm -rf %t
 // RUN: mkdir %t
 
index be9223016baff890ba7d3f435c6fea63f65ff458..0f1e3a242a158a938682063d4bbb1bf07735f620 100644 (file)
@@ -1,6 +1,3 @@
-// FIXME: PR43272
-// XFAIL: system-windows
-
 // RUN: rm -rf %t
 // RUN: mkdir %t
 
index 569c226c8684dd02ac18f2dca9c6694716751333..1e12c930c35ed0dcac71e10cc603e5bc6ca617f0 100644 (file)
@@ -1,9 +1,6 @@
 // RUN: sed -e "s@INPUT_DIR@%/S/Inputs@g" -e "s@OUT_DIR@%/t@g" -e "s@EXTERNAL_NAMES@true@" %S/Inputs/use-external-names.yaml > %t.external.yaml
 // RUN: sed -e "s@INPUT_DIR@%/S/Inputs@g" -e "s@OUT_DIR@%/t@g" -e "s@EXTERNAL_NAMES@false@" %S/Inputs/use-external-names.yaml > %t.yaml
 
-// FIXME: PR43272
-// XFAIL: system-windows
-
 #include "external-names.h"
 #ifdef REINCLUDE
 #include "external-names.h"
index 231a3884bb9ec93615fa45c33d8f3fed7414b7d8..858f1f57fbd15f1ff90b6adfe07d682e2f3bb262 100644 (file)
@@ -1,9 +1,6 @@
 // RUN: sed -e "s@INPUT_DIR@%/S/Inputs@g" -e "s@OUT_DIR@%/t@g" %S/Inputs/vfsoverlay.yaml > %t.yaml
 // RUN: %clang_cc1 -Werror -F %t -ivfsoverlay %t.yaml -fsyntax-only %s
 
-// FIXME: PR43272
-// XFAIL: system-windows
-
 #import <SomeFramework/public_header.h>
 
 void foo() {
index 39187417925ef343cf198017411591fb3f659043..654e0a87de0e7c4c315bf0a63515f421051072a2 100644 (file)
@@ -1,9 +1,6 @@
 // RUN: sed -e "s@INPUT_DIR@%/S/Inputs@g" -e "s@OUT_DIR@%/t@g" %S/Inputs/vfsoverlay.yaml > %t.yaml
 // RUN: %clang_cc1 -Werror -ivfsoverlay %t.yaml -I %t -include "not_real.h" -fsyntax-only %s
 
-// FIXME: PR43272
-// XFAIL: system-windows
-
 void foo() {
   bar();
 }
index 90b29640c6855ade2622b53e3aeb37404408f00e..e4297c5737d951a0403067506585d865ee69f309 100644 (file)
@@ -4,9 +4,6 @@
 // RUN: sed -e "s@INPUT_DIR@%/S/Inputs@g" -e "s@OUT_DIR@%/t@g" %S/Inputs/vfsoverlay.yaml > %t.yaml
 // RUN: %clang_cc1 -Werror -ivfsoverlay %t.yaml -I %t -fsyntax-only %s
 
-// FIXME: PR43272
-// XFAIL: system-windows
-
 #include "not_real.h"
 #include "real.h"
 
index dad71602ee00aa9a5e854db6dc05f5eb0eabe3fc..3a41c4ea2c76701303fd93a42f5e3b94dc9737e2 100644 (file)
@@ -4,9 +4,6 @@
 // RUN: sed -e "s@INPUT_DIR@%/S/Inputs@g" -e "s@OUT_DIR@%/t@g" %S/Inputs/vfsoverlay.yaml > %t.yaml
 // RUN: %clang_cc1 -Werror -ivfsoverlay %t.yaml -I %t -fsyntax-only %s
 
-// FIXME: PR43272
-// XFAIL: system-windows
-
 #include "include_real.h"
 
 void foo() {
index 60142a52f9a9c1076f39101b12019c39d3aa7dc7..0b0d4cd0025a57e10813243f97a9a555208a2b34 100644 (file)
@@ -4,9 +4,6 @@
 // RUN: sed -e "s@INPUT_DIR@%/S/Inputs@g" -e "s@OUT_DIR@%/t@g" %S/Inputs/vfsoverlay.yaml > %t.yaml
 // RUN: %clang_cc1 -Werror -ivfsoverlay %t.yaml -I %t -fsyntax-only %s
 
-// FIXME: PR43272
-// XFAIL: system-windows
-
 #include "include_not_real.h"
 
 void foo() {
index 5ece6cc9634b0579de0425f9e24feb1ef52d719b..16a1bca71a720166715fd88e509052d6b7178ff7 100644 (file)
@@ -1,9 +1,6 @@
 // RUN: sed -e "s@INPUT_DIR@%/S/Inputs@g" -e "s@OUT_DIR@%/t@g" %S/Inputs/vfsoverlay.yaml > %t.yaml
 // RUN: %clang_cc1 -Werror -I %t -ivfsoverlay %t.yaml -fsyntax-only %s
 
-// FIXME: PR43272
-// XFAIL: system-windows
-
 #include "not_real.h"
 
 void foo() {
index b8c22bda784c4b04cbfa3fd840113af0645818a6..5b2a1e0b4e1b1c35487cb6c713316c64f351a7c8 100644 (file)
@@ -5,9 +5,6 @@
 // RUN: not %clang_cc1 -Werror -fmodules -fimplicit-module-maps -fmodules-cache-path=%t \
 // RUN:     -ivfsoverlay %t.yaml -F %t -fsyntax-only %s 2>&1 | FileCheck %s
 
-// FIXME: PR43272
-// XFAIL: system-windows
-
 @import Incomplete;
 // CHECK: umbrella header for module 'Incomplete' {{.*}}IncompleteVFS.h
 // CHECK: umbrella header for module 'Incomplete' {{.*}}IncompleteReal.h
index 7557cb9555f328475566e034ca2a60753328909f..336a72d31cfa64df49b93950cbdb0a243506ba97 100644 (file)
@@ -2,9 +2,6 @@
 // RUN: sed -e "s@INPUT_DIR@%/S/Inputs@g" -e "s@OUT_DIR@%/t@g" %S/Inputs/vfsoverlay.yaml > %t.yaml
 // RUN: %clang_cc1 -Werror -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -ivfsoverlay %t.yaml -I %t -fsyntax-only %s
 
-// FIXME: PR43272
-// XFAIL: system-windows
-
 @import not_real;
 
 void foo() {
index 493222a76a3d6080e4b5a3a2c9f6e2908028ca13..8d7d21bf7832ed738c72753d6182531dda0d2961 100644 (file)
@@ -4,9 +4,6 @@
 // intentionally rebuild modules, since the precompiled module file refers to
 // the dependency files by real path.
 
-// FIXME: PR43272
-// XFAIL: system-windows
-
 // RUN: rm -rf %t %t-cache %t.pch
 // RUN: mkdir -p %t/SomeFramework.framework/Modules
 // RUN: cat %S/Inputs/some_frame_module.map > %t/SomeFramework.framework/Modules/module.modulemap
index 39360d5f781b93b3cd887714e500bfd433abd31c..fc4ae151d87f752c1b6a622459b731925c93b937 100644 (file)
@@ -3,9 +3,6 @@
 // RUN: sed -e "s@INPUT_DIR@%/S/Inputs@g" -e "s@OUT_DIR@%/t@g" %S/Inputs/vfsoverlay.yaml > %t.yaml
 // RUN: %clang_cc1 -Werror -I . -ivfsoverlay %t.yaml -fsyntax-only %s
 
-// FIXME: PR43272
-// XFAIL: system-windows
-
 #include "not_real.h"
 
 void foo() {
index 5ef48ed44a0e4c47bc505f2e46b61171a47f0f3e..6f536b40a91134252e60fa5d7b015d559fb99612 100644 (file)
@@ -1,8 +1,5 @@
 // REQUIRES: crash-recovery
 
-// FIXME: PR43272
-// XFAIL: system-windows
-
 // RUN: rm -rf %t
 // RUN: mkdir -p %t/vdir %t/outdir %t/cache
 // RUN: cp -R %S/Inputs/Bar.framework %t/outdir/
index cdbfdbf0c4db034924db8470f96ae5638d99a674..3b4c4aff9bdc7d555f51a83c7519e2107c4845d6 100644 (file)
@@ -532,7 +532,7 @@ class RedirectingFileSystemParser;
 /// \endverbatim
 ///
 /// All configuration options are optional.
-///   'case-sensitive': <boolean, default=true>
+///   'case-sensitive': <boolean, default=(true for Posix, false for Windows)>
 ///   'use-external-names': <boolean, default=true>
 ///   'overlay-relative': <boolean, default=false>
 ///   'fallthrough': <boolean, default=true>
@@ -651,6 +651,17 @@ private:
     return ExternalFSValidWD && IsFallthrough;
   }
 
+  // In a RedirectingFileSystem, keys can be specified in Posix or Windows
+  // style (or even a mixture of both), so this comparison helper allows
+  // slashes (representing a root) to match backslashes (and vice versa).  Note
+  // that, other than the root, patch components should not contain slashes or
+  // backslashes.
+  bool pathComponentMatches(llvm::StringRef lhs, llvm::StringRef rhs) const {
+    if ((CaseSensitive ? lhs.equals(rhs) : lhs.equals_lower(rhs)))
+      return true;
+    return (lhs == "/" && rhs == "\\") || (lhs == "\\" && rhs == "/");
+  }
+
   /// The root(s) of the virtual file system.
   std::vector<std::unique_ptr<Entry>> Roots;
 
@@ -674,7 +685,12 @@ private:
   /// Whether to perform case-sensitive comparisons.
   ///
   /// Currently, case-insensitive matching only works correctly with ASCII.
-  bool CaseSensitive = true;
+  bool CaseSensitive =
+#ifdef _WIN32
+      false;
+#else
+      true;
+#endif
 
   /// IsRelativeOverlay marks whether a ExternalContentsPrefixDir path must
   /// be prefixed in every 'external-contents' when reading from YAML files.
index 40b748eab18ee8670fb1380f5172294bb4eb8d1d..2d5c04baa57e0739d722f85d489f247d9d7aee97 100644 (file)
@@ -1671,9 +1671,7 @@ RedirectingFileSystem::lookupPath(sys::path::const_iterator Start,
 
   // Forward the search to the next component in case this is an empty one.
   if (!FromName.empty()) {
-    if (CaseSensitive ? !Start->equals(FromName)
-                      : !Start->equals_lower(FromName))
-      // failure to match
+    if (!pathComponentMatches(*Start, FromName))
       return make_error_code(llvm::errc::no_such_file_or_directory);
 
     ++Start;
@@ -1695,6 +1693,7 @@ RedirectingFileSystem::lookupPath(sys::path::const_iterator Start,
     if (Result || Result.getError() != llvm::errc::no_such_file_or_directory)
       return Result;
   }
+
   return make_error_code(llvm::errc::no_such_file_or_directory);
 }