Skip to content

Commit 2eb19b6

Browse files
authored
Merge pull request #3909 from bnbarham/cherry-redirecting-with
[VFS] Add a "redirecting-with" field to overlays
2 parents a40de57 + 9b93b7d commit 2eb19b6

File tree

7 files changed

+496
-84
lines changed

7 files changed

+496
-84
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
'redirecting-with': 'fallthrough',
3+
'fallthrough': true,
4+
'roots': [
5+
{
6+
'type': 'directory-remap',
7+
'name': '//root/a',
8+
'external-contents': '//root/b'
9+
}
10+
]
11+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
'redirecting-with': 'none',
3+
'roots': [
4+
{
5+
'type': 'directory-remap',
6+
'name': '//root/a',
7+
'external-contents': '//root/b'
8+
}
9+
]
10+
}

clang/test/VFS/fallback.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// RUN: rm -rf %t
2+
// RUN: split-file %s %t
3+
4+
// Test fallback directory remapping, ie. a directory "Base" which is used as
5+
// a fallback if files are missing from "UseFirst"
6+
7+
// RUN: sed -e "s@EXTERNAL_DIR@%{/t:regex_replacement}/Both/Base@g" -e "s@NAME_DIR@%{/t:regex_replacement}/Both/UseFirst@g" %t/vfs/base.yaml > %t/vfs/both.yaml
8+
9+
// RUN: cp -R %t/Both %t/UseFirstOnly
10+
// RUN: rm -rf %t/UseFirstOnly/Base
11+
// RUN: sed -e "s@EXTERNAL_DIR@%{/t:regex_replacement}/UseFirstOnly/Base@g" -e "s@NAME_DIR@%{/t:regex_replacement}/UseFirstOnly/UseFirst@g" %t/vfs/base.yaml > %t/vfs/use-first-only.yaml
12+
13+
// RUN: cp -R %t/Both %t/BaseOnly
14+
// RUN: rm -rf %t/BaseOnly/UseFirst
15+
// RUN: sed -e "s@EXTERNAL_DIR@%{/t:regex_replacement}/BaseOnly/Base@g" -e "s@NAME_DIR@%{/t:regex_replacement}/BaseOnly/UseFirst@g" %t/vfs/base.yaml > %t/vfs/base-only.yaml
16+
17+
// RUN: cp -R %t/Both %t/BFallback
18+
// RUN: rm %t/BFallback/UseFirst/B.h
19+
// RUN: sed -e "s@EXTERNAL_DIR@%{/t:regex_replacement}/BFallback/Base@g" -e "s@NAME_DIR@%{/t:regex_replacement}/BFallback/UseFirst@g" %t/vfs/base.yaml > %t/vfs/b-fallback.yaml
20+
21+
// RUN: cp -R %t/Both %t/CFallback
22+
// RUN: rm %t/CFallback/UseFirst/C.h
23+
// RUN: sed -e "s@EXTERNAL_DIR@%{/t:regex_replacement}/CFallback/Base@g" -e "s@NAME_DIR@%{/t:regex_replacement}/CFallback/UseFirst@g" %t/vfs/base.yaml > %t/vfs/c-fallback.yaml
24+
25+
// Both B.h and C.h are in both folders
26+
// RUN: %clang_cc1 -Werror -I %t/Both/UseFirst -ivfsoverlay %t/vfs/both.yaml -fsyntax-only -E -C %t/main.c 2>&1 | FileCheck --check-prefix=IN_UF %s
27+
28+
// IN_UF: # 1 "{{.*(/|\\\\)UseFirst(/|\\\\)}}B.h"
29+
// IN_UF-NEXT: // B.h in UseFirst
30+
// IN_UF: # 1 "{{.*(/|\\\\)UseFirst(/|\\\\)}}C.h"
31+
// IN_UF-NEXT: // C.h in UseFirst
32+
33+
// Base missing, so now they are only in UseFirst
34+
// RUN: %clang_cc1 -Werror -I %t/UseFirstOnly/UseFirst -ivfsoverlay %t/vfs/use-first-only.yaml -fsyntax-only -E -C %t/main.c 2>&1 | FileCheck --check-prefix=IN_UF %s
35+
36+
// UseFirst missing, fallback to Base
37+
// RUN: %clang_cc1 -Werror -I %t/BaseOnly/UseFirst -ivfsoverlay %t/vfs/base-only.yaml -fsyntax-only -E -C %t/main.c 2>&1 | FileCheck --check-prefix=IN_BASE %s
38+
39+
// IN_BASE: # 1 "{{.*(/|\\\\)Base(/|\\\\)}}B.h"
40+
// IN_BASE-NEXT: // B.h in Base
41+
// IN_BASE: # 1 "{{.*(/|\\\\)Base(/|\\\\)}}C.h"
42+
// IN_BASE-NEXT: // C.h in Base
43+
44+
// B.h missing from UseFirst
45+
// RUN: %clang_cc1 -Werror -I %t/BFallback/UseFirst -ivfsoverlay %t/vfs/b-fallback.yaml -fsyntax-only -E -C %t/main.c 2>&1 | FileCheck --check-prefix=B_FALLBACK %s
46+
47+
// B_FALLBACK: # 1 "{{.*(/|\\\\)Base(/|\\\\)}}B.h"
48+
// B_FALLBACK-NEXT: // B.h in Base
49+
// B_FALLBACK: # 1 "{{.*(/|\\\\)UseFirst(/|\\\\)}}C.h"
50+
// B_FALLBACK-NEXT: // C.h in UseFirst
51+
52+
// C.h missing from UseFirst
53+
// RUN: %clang_cc1 -Werror -I %t/CFallback/UseFirst -ivfsoverlay %t/vfs/c-fallback.yaml -fsyntax-only -E -C %t/main.c 2>&1 | FileCheck --check-prefix=C_FALLBACK %s
54+
55+
// C_FALLBACK: # 1 "{{.*(/|\\\\)UseFirst(/|\\\\)}}B.h"
56+
// C_FALLBACK-NEXT: // B.h in UseFirst
57+
// C_FALLBACK: # 1 "{{.*(/|\\\\)Base(/|\\\\)}}C.h"
58+
// C_FALLBACK-NEXT: // C.h in Base
59+
60+
//--- main.c
61+
#include "B.h"
62+
63+
//--- Both/UseFirst/B.h
64+
// B.h in UseFirst
65+
#include "C.h"
66+
67+
//--- Both/UseFirst/C.h
68+
// C.h in UseFirst
69+
70+
//--- Both/Base/B.h
71+
// B.h in Base
72+
#include "C.h"
73+
74+
//--- Both/Base/C.h
75+
// C.h in Base
76+
77+
//--- vfs/base.yaml
78+
{
79+
'version' : 0,
80+
'redirecting-with' : 'fallback',
81+
'roots' : [
82+
{'name' : 'NAME_DIR',
83+
'type' : 'directory-remap',
84+
'external-contents' : 'EXTERNAL_DIR'}
85+
]
86+
}

clang/test/VFS/parse-errors.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,11 @@
1212
// RUN: not %clang_cc1 -ivfsoverlay %S/Inputs/unknown-value.yaml -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-UNKNOWN-VALUE %s
1313
// CHECK-UNKNOWN-VALUE: expected boolean value
1414
// CHECK-UNKNOWN-VALUE: invalid virtual filesystem overlay file
15+
16+
// RUN: not %clang_cc1 -ivfsoverlay %S/Inputs/unknown-redirect.yaml -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-REDIRECT %s
17+
// CHECK-REDIRECT: expected valid redirect kind
18+
// CHECK-REDIRECT: invalid virtual filesystem overlay file
19+
20+
// RUN: not %clang_cc1 -ivfsoverlay %S/Inputs/redirect-and-fallthrough.yaml -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-EXCLUSIVE-KEYS %s
21+
// CHECK-EXCLUSIVE-KEYS: 'fallthrough' and 'redirecting-with' are mutually exclusive
22+
// CHECK-EXCLUSIVE-KEYS: invalid virtual filesystem overlay file

llvm/include/llvm/Support/VirtualFileSystem.h

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,10 @@ class RedirectingFileSystemParser;
549549
/// 'case-sensitive': <boolean, default=(true for Posix, false for Windows)>
550550
/// 'use-external-names': <boolean, default=true>
551551
/// 'overlay-relative': <boolean, default=false>
552-
/// 'fallthrough': <boolean, default=true>
552+
/// 'fallthrough': <boolean, default=true, deprecated - use 'redirecting-with'
553+
/// instead>
554+
/// 'redirecting-with': <string, one of 'fallthrough', 'fallback', or
555+
/// 'redirect-only', default='fallthrough'>
553556
///
554557
/// Virtual directories that list their contents are represented as
555558
/// \verbatim
@@ -620,6 +623,20 @@ class RedirectingFileSystem : public vfs::FileSystem {
620623
enum EntryKind { EK_Directory, EK_DirectoryRemap, EK_File };
621624
enum NameKind { NK_NotSet, NK_External, NK_Virtual };
622625

626+
/// The type of redirection to perform.
627+
enum class RedirectKind {
628+
/// Lookup the redirected path first (ie. the one specified in
629+
/// 'external-contents') and if that fails "fallthrough" to a lookup of the
630+
/// originally provided path.
631+
Fallthrough,
632+
/// Lookup the provided path first and if that fails, "fallback" to a
633+
/// lookup of the redirected path.
634+
Fallback,
635+
/// Only lookup the redirected path, do not lookup the originally provided
636+
/// path.
637+
RedirectOnly
638+
};
639+
623640
/// A single file or directory in the VFS.
624641
class Entry {
625642
EntryKind Kind;
@@ -754,17 +771,11 @@ class RedirectingFileSystem : public vfs::FileSystem {
754771
friend class RedirectingFSDirIterImpl;
755772
friend class RedirectingFileSystemParser;
756773

757-
bool shouldUseExternalFS() const { return IsFallthrough; }
758-
759774
/// Canonicalize path by removing ".", "..", "./", components. This is
760775
/// a VFS request, do not bother about symlinks in the path components
761776
/// but canonicalize in order to perform the correct entry search.
762777
std::error_code makeCanonical(SmallVectorImpl<char> &Path) const;
763778

764-
/// Whether to fall back to the external file system when an operation fails
765-
/// with the given error code on a path associated with the provided Entry.
766-
bool shouldFallBackToExternalFS(std::error_code EC, Entry *E = nullptr) const;
767-
768779
/// Get the File status, or error, from the underlying external file system.
769780
/// This returns the status with the originally requested name, while looking
770781
/// up the entry using the canonical path.
@@ -817,9 +828,9 @@ class RedirectingFileSystem : public vfs::FileSystem {
817828
/// names of files. This global value is overridable on a per-file basis.
818829
bool UseExternalNames = true;
819830

820-
/// Whether to attempt a file lookup in external file system after it wasn't
821-
/// found in VFS.
822-
bool IsFallthrough = true;
831+
/// Determines the lookups to perform, as well as their order. See
832+
/// \c RedirectKind for details.
833+
RedirectKind Redirection = RedirectKind::Fallthrough;
823834
/// @}
824835

825836
RedirectingFileSystem(IntrusiveRefCntPtr<FileSystem> ExternalFS);
@@ -874,8 +885,12 @@ class RedirectingFileSystem : public vfs::FileSystem {
874885

875886
StringRef getExternalContentsPrefixDir() const;
876887

888+
/// Sets the redirection kind to \c Fallthrough if true or \c RedirectOnly
889+
/// otherwise. Will removed in the future, use \c setRedirection instead.
877890
void setFallthrough(bool Fallthrough);
878891

892+
void setRedirection(RedirectingFileSystem::RedirectKind Kind);
893+
879894
std::vector<llvm::StringRef> getRoots() const;
880895

881896
void dump(raw_ostream &OS) const;

0 commit comments

Comments
 (0)