summaryrefslogtreecommitdiff
path: root/test/VFS
diff options
context:
space:
mode:
Diffstat (limited to 'test/VFS')
-rw-r--r--test/VFS/Inputs/Foo.framework/Headers/Foo.h0
-rw-r--r--test/VFS/Inputs/Foo.framework/Modules/module.modulemap3
-rw-r--r--test/VFS/Inputs/Foo.h0
-rw-r--r--test/VFS/Inputs/Incomplete.h1
-rw-r--r--test/VFS/Inputs/IncompleteVFS.h1
-rw-r--r--test/VFS/Inputs/actual_header.h1
-rw-r--r--test/VFS/Inputs/actual_module.map8
-rw-r--r--test/VFS/Inputs/actual_module2.map5
-rw-r--r--test/VFS/Inputs/external-names.h4
-rw-r--r--test/VFS/Inputs/import_some_frame.h2
-rw-r--r--test/VFS/Inputs/include_real.h1
-rw-r--r--test/VFS/Inputs/incomplete-umbrella.modulemap5
-rw-r--r--test/VFS/Inputs/invalid-yaml.yaml4
-rw-r--r--test/VFS/Inputs/missing-key.yaml4
-rw-r--r--test/VFS/Inputs/public_header.h2
-rw-r--r--test/VFS/Inputs/public_header2.h1
-rw-r--r--test/VFS/Inputs/some_frame_module.map5
-rw-r--r--test/VFS/Inputs/unknown-key.yaml5
-rw-r--r--test/VFS/Inputs/unknown-value.yaml5
-rw-r--r--test/VFS/Inputs/use-external-names.yaml7
-rw-r--r--test/VFS/Inputs/vfsoverlay.yaml53
-rw-r--r--test/VFS/Inputs/vfsoverlay2.yaml12
-rw-r--r--test/VFS/external-names.c35
-rw-r--r--test/VFS/framework-import.m9
-rw-r--r--test/VFS/implicit-include.c7
-rw-r--r--test/VFS/include-mixed-real-and-virtual.c14
-rw-r--r--test/VFS/include-real-from-virtual.c12
-rw-r--r--test/VFS/include-virtual-from-real.c12
-rw-r--r--test/VFS/include.c9
-rw-r--r--test/VFS/incomplete-umbrella.m12
-rw-r--r--test/VFS/module-import.m27
-rw-r--r--test/VFS/parse-errors.c14
-rw-r--r--test/VFS/real-path-found-first.m74
-rw-r--r--test/VFS/relative-path.c11
-rw-r--r--test/VFS/umbrella-mismatch.m8
35 files changed, 373 insertions, 0 deletions
diff --git a/test/VFS/Inputs/Foo.framework/Headers/Foo.h b/test/VFS/Inputs/Foo.framework/Headers/Foo.h
new file mode 100644
index 0000000000000..e69de29bb2d1d
--- /dev/null
+++ b/test/VFS/Inputs/Foo.framework/Headers/Foo.h
diff --git a/test/VFS/Inputs/Foo.framework/Modules/module.modulemap b/test/VFS/Inputs/Foo.framework/Modules/module.modulemap
new file mode 100644
index 0000000000000..0aab69f0af42f
--- /dev/null
+++ b/test/VFS/Inputs/Foo.framework/Modules/module.modulemap
@@ -0,0 +1,3 @@
+framework module Foo {
+ umbrella header "Foo.h"
+}
diff --git a/test/VFS/Inputs/Foo.h b/test/VFS/Inputs/Foo.h
new file mode 100644
index 0000000000000..e69de29bb2d1d
--- /dev/null
+++ b/test/VFS/Inputs/Foo.h
diff --git a/test/VFS/Inputs/Incomplete.h b/test/VFS/Inputs/Incomplete.h
new file mode 100644
index 0000000000000..29fafc3ccf8c9
--- /dev/null
+++ b/test/VFS/Inputs/Incomplete.h
@@ -0,0 +1 @@
+// does not include IncompleteVFS.h or IncompleteReal.h
diff --git a/test/VFS/Inputs/IncompleteVFS.h b/test/VFS/Inputs/IncompleteVFS.h
new file mode 100644
index 0000000000000..22cfe7d6ad548
--- /dev/null
+++ b/test/VFS/Inputs/IncompleteVFS.h
@@ -0,0 +1 @@
+// IncompleteVFS.h
diff --git a/test/VFS/Inputs/actual_header.h b/test/VFS/Inputs/actual_header.h
new file mode 100644
index 0000000000000..f61e58620c652
--- /dev/null
+++ b/test/VFS/Inputs/actual_header.h
@@ -0,0 +1 @@
+void bar(void);
diff --git a/test/VFS/Inputs/actual_module.map b/test/VFS/Inputs/actual_module.map
new file mode 100644
index 0000000000000..d2f5b64a38d31
--- /dev/null
+++ b/test/VFS/Inputs/actual_module.map
@@ -0,0 +1,8 @@
+module not_real {
+ header "not_real.h"
+ export *
+}
+module import_some_frame {
+ header "import_some_frame.h"
+ export *
+}
diff --git a/test/VFS/Inputs/actual_module2.map b/test/VFS/Inputs/actual_module2.map
new file mode 100644
index 0000000000000..24f860299f3a7
--- /dev/null
+++ b/test/VFS/Inputs/actual_module2.map
@@ -0,0 +1,5 @@
+module not_real {
+ header "not_real.h"
+ export *
+ explicit module from_second_vfs { }
+}
diff --git a/test/VFS/Inputs/external-names.h b/test/VFS/Inputs/external-names.h
new file mode 100644
index 0000000000000..8b0baa3f02342
--- /dev/null
+++ b/test/VFS/Inputs/external-names.h
@@ -0,0 +1,4 @@
+void foo(char **c) {
+ *c = __FILE__;
+ int x = c; // produce a diagnostic
+}
diff --git a/test/VFS/Inputs/import_some_frame.h b/test/VFS/Inputs/import_some_frame.h
new file mode 100644
index 0000000000000..c1f68c83fc581
--- /dev/null
+++ b/test/VFS/Inputs/import_some_frame.h
@@ -0,0 +1,2 @@
+#import <SomeFramework/public_header.h>
+#import <SomeFramework/public_header2.h>
diff --git a/test/VFS/Inputs/include_real.h b/test/VFS/Inputs/include_real.h
new file mode 100644
index 0000000000000..0750c6527221e
--- /dev/null
+++ b/test/VFS/Inputs/include_real.h
@@ -0,0 +1 @@
+#include "real.h"
diff --git a/test/VFS/Inputs/incomplete-umbrella.modulemap b/test/VFS/Inputs/incomplete-umbrella.modulemap
new file mode 100644
index 0000000000000..5afac9272298f
--- /dev/null
+++ b/test/VFS/Inputs/incomplete-umbrella.modulemap
@@ -0,0 +1,5 @@
+framework module Incomplete {
+ umbrella header "Incomplete.h"
+ export *
+ module * { export * }
+}
diff --git a/test/VFS/Inputs/invalid-yaml.yaml b/test/VFS/Inputs/invalid-yaml.yaml
new file mode 100644
index 0000000000000..2a6c6667ce4da
--- /dev/null
+++ b/test/VFS/Inputs/invalid-yaml.yaml
@@ -0,0 +1,4 @@
+{
+ 'version': 0,
+ 'roots': []
+]
diff --git a/test/VFS/Inputs/missing-key.yaml b/test/VFS/Inputs/missing-key.yaml
new file mode 100644
index 0000000000000..5d18c244ee569
--- /dev/null
+++ b/test/VFS/Inputs/missing-key.yaml
@@ -0,0 +1,4 @@
+{
+ 'version': 0,
+ 'roots': [ { 'name' : 'foo', 'external-contents': 'bar' } ]
+}
diff --git a/test/VFS/Inputs/public_header.h b/test/VFS/Inputs/public_header.h
new file mode 100644
index 0000000000000..09d9969d319d9
--- /dev/null
+++ b/test/VFS/Inputs/public_header.h
@@ -0,0 +1,2 @@
+#import <SomeFramework/public_header2.h>
+void from_framework(void);
diff --git a/test/VFS/Inputs/public_header2.h b/test/VFS/Inputs/public_header2.h
new file mode 100644
index 0000000000000..d883613ac120e
--- /dev/null
+++ b/test/VFS/Inputs/public_header2.h
@@ -0,0 +1 @@
+// public_header2.h
diff --git a/test/VFS/Inputs/some_frame_module.map b/test/VFS/Inputs/some_frame_module.map
new file mode 100644
index 0000000000000..3ce59b254d83c
--- /dev/null
+++ b/test/VFS/Inputs/some_frame_module.map
@@ -0,0 +1,5 @@
+framework module SomeFramework {
+ umbrella header "public_header.h"
+ export *
+ module * { export * }
+}
diff --git a/test/VFS/Inputs/unknown-key.yaml b/test/VFS/Inputs/unknown-key.yaml
new file mode 100644
index 0000000000000..ec7d8261d95fe
--- /dev/null
+++ b/test/VFS/Inputs/unknown-key.yaml
@@ -0,0 +1,5 @@
+{
+ 'version': 0,
+ 'unknown-key': 'value',
+ 'roots': []
+}
diff --git a/test/VFS/Inputs/unknown-value.yaml b/test/VFS/Inputs/unknown-value.yaml
new file mode 100644
index 0000000000000..4e90b2134cc8e
--- /dev/null
+++ b/test/VFS/Inputs/unknown-value.yaml
@@ -0,0 +1,5 @@
+{
+ 'version': 0,
+ 'case-sensitive': 'Maybe?',
+ 'roots': []
+}
diff --git a/test/VFS/Inputs/use-external-names.yaml b/test/VFS/Inputs/use-external-names.yaml
new file mode 100644
index 0000000000000..b9ea6342cf0b2
--- /dev/null
+++ b/test/VFS/Inputs/use-external-names.yaml
@@ -0,0 +1,7 @@
+{
+ 'version': 0,
+ 'use-external-names': EXTERNAL_NAMES,
+ 'roots': [{ 'type': 'file', 'name': 'OUT_DIR/external-names.h',
+ 'external-contents': 'INPUT_DIR/external-names.h'
+ }]
+}
diff --git a/test/VFS/Inputs/vfsoverlay.yaml b/test/VFS/Inputs/vfsoverlay.yaml
new file mode 100644
index 0000000000000..f395d45ee3b7e
--- /dev/null
+++ b/test/VFS/Inputs/vfsoverlay.yaml
@@ -0,0 +1,53 @@
+{
+ 'version': 0,
+ 'roots': [
+ { 'name': 'OUT_DIR', 'type': 'directory',
+ 'contents': [
+ { 'name': 'not_real.h', 'type': 'file',
+ 'external-contents': 'INPUT_DIR/actual_header.h'
+ },
+ { 'name': 'import_some_frame.h', 'type': 'file',
+ 'external-contents': 'INPUT_DIR/import_some_frame.h'
+ },
+ { 'name': 'module.map', 'type': 'file',
+ 'external-contents': 'INPUT_DIR/actual_module.map'
+ },
+ { 'name': 'include_real.h', 'type': 'file',
+ 'external-contents': 'INPUT_DIR/include_real.h'
+ },
+ { 'name': 'SomeFramework.framework', 'type': 'directory',
+ 'contents': [
+ { 'name': 'Headers', 'type': 'directory',
+ 'contents': [
+ { 'name': 'public_header.h', 'type': 'file',
+ 'external-contents': 'INPUT_DIR/public_header.h' },
+ { 'name': 'public_header2.h', 'type': 'file',
+ 'external-contents': 'INPUT_DIR/public_header2.h' }
+ ]
+ }
+ ]
+ },
+ { 'name': 'Foo.framework/Headers/Foo.h', 'type': 'file',
+ 'external-contents': 'INPUT_DIR/Foo.h'
+ },
+ { 'name': 'Incomplete.framework', 'type': 'directory',
+ 'contents': [
+ { 'name': 'Headers', 'type': 'directory',
+ 'contents': [
+ { 'name': 'Incomplete.h', 'type': 'file',
+ 'external-contents': 'INPUT_DIR/Incomplete.h'
+ },
+ { 'name': 'IncompleteVFS.h', 'type': 'file',
+ 'external-contents': 'INPUT_DIR/IncompleteVFS.h'
+ }
+ ]
+ },
+ { 'name': 'Modules/module.modulemap', 'type': 'file',
+ 'external-contents': 'INPUT_DIR/incomplete-umbrella.modulemap'
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/test/VFS/Inputs/vfsoverlay2.yaml b/test/VFS/Inputs/vfsoverlay2.yaml
new file mode 100644
index 0000000000000..ae2a0ce4ec98f
--- /dev/null
+++ b/test/VFS/Inputs/vfsoverlay2.yaml
@@ -0,0 +1,12 @@
+{
+ 'version': 0,
+ 'roots': [
+ { 'name': 'OUT_DIR', 'type': 'directory',
+ 'contents': [
+ { 'name': 'module.map', 'type': 'file',
+ 'external-contents': 'INPUT_DIR/actual_module2.map'
+ }
+ ]
+ }
+ ]
+}
diff --git a/test/VFS/external-names.c b/test/VFS/external-names.c
new file mode 100644
index 0000000000000..aa0bd6745309b
--- /dev/null
+++ b/test/VFS/external-names.c
@@ -0,0 +1,35 @@
+// 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
+// REQUIRES: shell
+
+#include "external-names.h"
+
+////
+// Preprocessor (__FILE__ macro and # directives):
+
+// RUN: %clang_cc1 -I %t -ivfsoverlay %t.external.yaml -E %s | FileCheck -check-prefix=CHECK-PP-EXTERNAL %s
+// CHECK-PP-EXTERNAL: # {{[0-9]*}} "[[NAME:.*Inputs.external-names.h]]"
+// CHECK-PP-EXTERNAL-NEXT: void foo(char **c) {
+// CHECK-PP-EXTERNAL-NEXT: *c = "[[NAME]]";
+
+// RUN: %clang_cc1 -I %t -ivfsoverlay %t.yaml -E %s | FileCheck -check-prefix=CHECK-PP %s
+// CHECK-PP-NOT: Inputs
+
+////
+// Diagnostics:
+
+// RUN: %clang_cc1 -I %t -ivfsoverlay %t.external.yaml -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-DIAG-EXTERNAL %s
+// CHECK-DIAG-EXTERNAL: {{.*}}Inputs{{.}}external-names.h:{{[0-9]*:[0-9]*}}: warning: incompatible pointer
+
+// RUN: %clang_cc1 -I %t -ivfsoverlay %t.yaml -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-DIAG %s
+// CHECK-DIAG-NOT: Inputs
+
+////
+// Debug info
+
+// RUN: %clang_cc1 -I %t -ivfsoverlay %t.external.yaml -triple %itanium_abi_triple -g -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-DEBUG-EXTERNAL %s
+// CHECK-DEBUG-EXTERNAL: ![[Num:[0-9]*]] = metadata !{metadata !"{{.*}}Inputs{{.}}external-names.h
+// CHECK-DEBUG-EXTERNAL: metadata !{i32 {{[0-9]*}}, metadata ![[Num]]{{.*}}DW_TAG_file_type
+
+// RUN: %clang_cc1 -I %t -ivfsoverlay %t.yaml -triple %itanium_abi_triple -g -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-DEBUG %s
+// CHECK-DEBUG-NOT: Inputs
diff --git a/test/VFS/framework-import.m b/test/VFS/framework-import.m
new file mode 100644
index 0000000000000..b40bc549c0a93
--- /dev/null
+++ b/test/VFS/framework-import.m
@@ -0,0 +1,9 @@
+// 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
+// REQUIRES: shell
+
+#import <SomeFramework/public_header.h>
+
+void foo() {
+ from_framework();
+}
diff --git a/test/VFS/implicit-include.c b/test/VFS/implicit-include.c
new file mode 100644
index 0000000000000..acf665bee2481
--- /dev/null
+++ b/test/VFS/implicit-include.c
@@ -0,0 +1,7 @@
+// 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
+// REQUIRES: shell
+
+void foo() {
+ bar();
+}
diff --git a/test/VFS/include-mixed-real-and-virtual.c b/test/VFS/include-mixed-real-and-virtual.c
new file mode 100644
index 0000000000000..e1f5f952cd4e9
--- /dev/null
+++ b/test/VFS/include-mixed-real-and-virtual.c
@@ -0,0 +1,14 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: echo "void baz(void);" > %t/real.h
+// 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
+// REQUIRES: shell
+
+#include "not_real.h"
+#include "real.h"
+
+void foo() {
+ bar();
+ baz();
+}
diff --git a/test/VFS/include-real-from-virtual.c b/test/VFS/include-real-from-virtual.c
new file mode 100644
index 0000000000000..65707b551643e
--- /dev/null
+++ b/test/VFS/include-real-from-virtual.c
@@ -0,0 +1,12 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: echo "void baz(void);" > %t/real.h
+// 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
+// REQUIRES: shell
+
+#include "include_real.h"
+
+void foo() {
+ baz();
+}
diff --git a/test/VFS/include-virtual-from-real.c b/test/VFS/include-virtual-from-real.c
new file mode 100644
index 0000000000000..c8f6059608d7b
--- /dev/null
+++ b/test/VFS/include-virtual-from-real.c
@@ -0,0 +1,12 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: echo '#include "not_real.h"' > %t/include_not_real.h
+// 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
+// REQUIRES: shell
+
+#include "include_not_real.h"
+
+void foo() {
+ bar();
+}
diff --git a/test/VFS/include.c b/test/VFS/include.c
new file mode 100644
index 0000000000000..8cd04dd45212c
--- /dev/null
+++ b/test/VFS/include.c
@@ -0,0 +1,9 @@
+// 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
+// REQUIRES: shell
+
+#include "not_real.h"
+
+void foo() {
+ bar();
+}
diff --git a/test/VFS/incomplete-umbrella.m b/test/VFS/incomplete-umbrella.m
new file mode 100644
index 0000000000000..4e138cc0f3385
--- /dev/null
+++ b/test/VFS/incomplete-umbrella.m
@@ -0,0 +1,12 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/Incomplete.framework/Headers
+// RUN: echo '// IncompleteReal.h' > %t/Incomplete.framework/Headers/IncompleteReal.h
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/vfsoverlay.yaml > %t.yaml
+// RUN: not %clang_cc1 -Werror -fmodules -fmodules-cache-path=%t \
+// RUN: -ivfsoverlay %t.yaml -F %t -fsyntax-only %s 2>&1 | FileCheck %s
+// REQUIRES: shell
+
+@import Incomplete;
+// CHECK: umbrella header for module 'Incomplete' {{.*}}IncompleteVFS.h
+// CHECK: umbrella header for module 'Incomplete' {{.*}}IncompleteReal.h
+// CHECK: could not build module 'Incomplete'
diff --git a/test/VFS/module-import.m b/test/VFS/module-import.m
new file mode 100644
index 0000000000000..d2adcfedfaa82
--- /dev/null
+++ b/test/VFS/module-import.m
@@ -0,0 +1,27 @@
+// RUN: rm -rf %t
+// 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 -fmodules-cache-path=%t -ivfsoverlay %t.yaml -I %t -fsyntax-only %s
+// REQUIRES: shell
+
+@import not_real;
+
+void foo() {
+ bar();
+}
+
+// Import a submodule that is defined in actual_module2.map, which is only
+// mapped in vfsoverlay2.yaml.
+#ifdef IMPORT2
+@import not_real.from_second_module;
+// CHECK-VFS2: error: no submodule
+#endif
+
+// Override the module map (vfsoverlay2 on top)
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/vfsoverlay2.yaml > %t2.yaml
+// RUN: %clang_cc1 -Werror -fmodules -fmodules-cache-path=%t -ivfsoverlay %t.yaml -ivfsoverlay %t2.yaml -I %t -fsyntax-only %s
+
+// vfsoverlay2 not present
+// RUN: not %clang_cc1 -Werror -fmodules -fmodules-cache-path=%t -ivfsoverlay %t.yaml -I %t -fsyntax-only %s -DIMPORT2 2>&1 | FileCheck -check-prefix=CHECK-VFS2 %s
+
+// vfsoverlay2 on the bottom
+// RUN: not %clang_cc1 -Werror -fmodules -fmodules-cache-path=%t -ivfsoverlay %t2.yaml -ivfsoverlay %t.yaml -I %t -fsyntax-only %s -DIMPORT2 2>&1 | FileCheck -check-prefix=CHECK-VFS2 %s
diff --git a/test/VFS/parse-errors.c b/test/VFS/parse-errors.c
new file mode 100644
index 0000000000000..7194efc65a5d6
--- /dev/null
+++ b/test/VFS/parse-errors.c
@@ -0,0 +1,14 @@
+// RUN: not %clang_cc1 -ivfsoverlay %S/Inputs/invalid-yaml.yaml -fsyntax-only %s 2>&1 | FileCheck %s
+// CHECK: invalid virtual filesystem overlay file
+
+// RUN: not %clang_cc1 -ivfsoverlay %S/Inputs/missing-key.yaml -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-MISSING-TYPE %s
+// CHECK-MISSING-TYPE: missing key 'type'
+// CHECK-MISSING-TYPE: invalid virtual filesystem overlay file
+
+// RUN: not %clang_cc1 -ivfsoverlay %S/Inputs/unknown-key.yaml -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-UNKNOWN-KEY %s
+// CHECK-UNKNOWN-KEY: unknown key
+// CHECK-UNKNOWN-KEY: invalid virtual filesystem overlay file
+
+// RUN: not %clang_cc1 -ivfsoverlay %S/Inputs/unknown-value.yaml -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-UNKNOWN-VALUE %s
+// CHECK-UNKNOWN-VALUE: expected boolean value
+// CHECK-UNKNOWN-VALUE: invalid virtual filesystem overlay file
diff --git a/test/VFS/real-path-found-first.m b/test/VFS/real-path-found-first.m
new file mode 100644
index 0000000000000..f494c6eb1534f
--- /dev/null
+++ b/test/VFS/real-path-found-first.m
@@ -0,0 +1,74 @@
+// This test is for cases where we lookup a file by its 'real' path before we
+// use its VFS-mapped path. If we accidentally use the real path in header
+// search, we will not find a module for the headers. To test that we
+// intentionally rebuild modules, since the precompiled module file refers to
+// the dependency files by real path.
+
+// REQUIRES: shell
+// RUN: rm -rf %t %t-cache %t.pch
+// RUN: mkdir -p %t/SomeFramework.framework/Modules
+// RUN: cp %S/Inputs/some_frame_module.map %t/SomeFramework.framework/Modules/module.modulemap
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/vfsoverlay.yaml > %t.yaml
+
+// Build
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN: -ivfsoverlay %t.yaml -fsyntax-only %s -verify -Wauto-import \
+// RUN: -Werror=non-modular-include-in-framework-module
+
+// Rebuild
+// RUN: echo ' ' >> %t/SomeFramework.framework/Modules/module.modulemap
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN: -ivfsoverlay %t.yaml -fsyntax-only %s -verify -Wauto-import \
+// RUN: -Werror=non-modular-include-in-framework-module
+
+// Load from PCH
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN: -ivfsoverlay %t.yaml -emit-pch %s -o %t.pch \
+// RUN: -Werror=non-modular-include-in-framework-module \
+// RUN: -fmodules-ignore-macro=WITH_PREFIX
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN: -ivfsoverlay %t.yaml -include-pch %t.pch -fsyntax-only %s \
+// RUN: -Werror=non-modular-include-in-framework-module -DWITH_PREFIX \
+// RUN: -fmodules-ignore-macro=WITH_PREFIX
+
+// While indexing
+// RUN: c-index-test -index-file %s -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN: -ivfsoverlay %t.yaml -fsyntax-only -Wauto-import \
+// RUN: -Werror=non-modular-include-in-framework-module | FileCheck %s
+// RUN: echo ' ' >> %t/SomeFramework.framework/Modules/module.modulemap
+// RUN: c-index-test -index-file %s -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN: -ivfsoverlay %t.yaml -fsyntax-only -Wauto-import \
+// RUN: -Werror=non-modular-include-in-framework-module | FileCheck %s
+// CHECK: warning: treating
+// CHECK-NOT: error
+
+// With a VFS-mapped module map file
+// RUN: mv %t/SomeFramework.framework/Modules/module.modulemap %t/hide_module.map
+// RUN: echo "{ 'version': 0, 'roots': [ { " > %t2.yaml
+// RUN: echo "'name': '%t/SomeFramework.framework/Modules/module.modulemap'," >> %t2.yaml
+// RUN: echo "'type': 'file', 'external-contents': '%t/hide_module.map' } ] }" >> %t2.yaml
+
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN: -ivfsoverlay %t.yaml -ivfsoverlay %t2.yaml -fsyntax-only %s -verify \
+// RUN: -Wauto-import -Werror=non-modular-include-in-framework-module
+// RUN: echo ' ' >> %t/hide_module.map
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN: -ivfsoverlay %t.yaml -ivfsoverlay %t2.yaml -fsyntax-only %s -verify \
+// RUN: -Wauto-import -Werror=non-modular-include-in-framework-module
+
+// Within a module build
+// RUN: echo '@import import_some_frame;' | \
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN: -ivfsoverlay %t.yaml -ivfsoverlay %t2.yaml -fsyntax-only - \
+// RUN: -Werror=non-modular-include-in-framework-module -x objective-c -I %t
+// RUN: echo ' ' >> %t/hide_module.map
+// RUN: echo '@import import_some_frame;' | \
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN: -ivfsoverlay %t.yaml -ivfsoverlay %t2.yaml -fsyntax-only - \
+// RUN: -Werror=non-modular-include-in-framework-module -x objective-c -I %t
+
+#ifndef WITH_PREFIX
+#import <SomeFramework/public_header.h> // expected-warning{{treating}}
+#import <SomeFramework/public_header2.h> // expected-warning{{treating}}
+@import SomeFramework.public_header2;
+#endif
diff --git a/test/VFS/relative-path.c b/test/VFS/relative-path.c
new file mode 100644
index 0000000000000..e7101fb3a8267
--- /dev/null
+++ b/test/VFS/relative-path.c
@@ -0,0 +1,11 @@
+// RUN: mkdir -p %t
+// RUN: cd %t
+// 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
+// REQUIRES: shell
+
+#include "not_real.h"
+
+void foo() {
+ bar();
+}
diff --git a/test/VFS/umbrella-mismatch.m b/test/VFS/umbrella-mismatch.m
new file mode 100644
index 0000000000000..c73129448c55b
--- /dev/null
+++ b/test/VFS/umbrella-mismatch.m
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%S/Inputs:g" %S/Inputs/vfsoverlay.yaml > %t.yaml
+// REQUIRES: shell
+
+// RUN: %clang_cc1 -Werror -fmodules -fmodules-cache-path=%t -ivfsoverlay %t.yaml -F %S/Inputs -fsyntax-only %s -verify
+// RUN: %clang_cc1 -Werror -fmodules -fmodules-cache-path=%t -F %S/Inputs -fsyntax-only %s -verify
+// expected-no-diagnostics
+@import Foo;