summaryrefslogtreecommitdiff
path: root/test/Modules
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-07-23 20:44:14 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-07-23 20:44:14 +0000
commit2b6b257f4e5503a7a2675bdb8735693db769f75c (patch)
treee85e046ae7003fe3bcc8b5454cd0fa3f7407b470 /test/Modules
parentb4348ed0b7e90c0831b925fbee00b5f179a99796 (diff)
Notes
Diffstat (limited to 'test/Modules')
-rw-r--r--test/Modules/DebugInfoSubmoduleImport.c2
-rw-r--r--test/Modules/DebugInfoTransitiveImport.m8
-rw-r--r--test/Modules/ExtDebugInfo.cpp138
-rw-r--r--test/Modules/ExtDebugInfo.m49
-rw-r--r--test/Modules/Inputs/DebugCXX.h49
-rw-r--r--test/Modules/Inputs/DebugObjC.h20
-rw-r--r--test/Modules/Inputs/MacroFabs1.h6
-rw-r--r--test/Modules/Inputs/MethodPoolCombined1.h6
-rw-r--r--test/Modules/Inputs/MethodPoolCombined2.h1
-rw-r--r--test/Modules/Inputs/MethodPoolString1.h4
-rw-r--r--test/Modules/Inputs/MethodPoolString2.h4
-rw-r--r--test/Modules/Inputs/PR21547/FirstHeader.h13
-rw-r--r--test/Modules/Inputs/PR21547/module.modulemap4
-rw-r--r--test/Modules/Inputs/PR24954/A.h10
-rw-r--r--test/Modules/Inputs/PR24954/B.h30
-rw-r--r--test/Modules/Inputs/PR24954/module.modulemap9
-rw-r--r--test/Modules/Inputs/PR25501/Vector.h5
-rw-r--r--test/Modules/Inputs/PR25501/a0.h1
-rw-r--r--test/Modules/Inputs/PR25501/a1.h1
-rw-r--r--test/Modules/Inputs/PR25501/a2.h3
-rw-r--r--test/Modules/Inputs/PR25501/b.h2
-rw-r--r--test/Modules/Inputs/PR25501/module.modulemap4
-rw-r--r--test/Modules/Inputs/PR26014/A.h13
-rw-r--r--test/Modules/Inputs/PR26014/B.h10
-rw-r--r--test/Modules/Inputs/PR26014/module.modulemap9
-rw-r--r--test/Modules/Inputs/PR26179/A.h2
-rw-r--r--test/Modules/Inputs/PR26179/B.h1
-rw-r--r--test/Modules/Inputs/PR26179/basic_string.h12
-rw-r--r--test/Modules/Inputs/PR26179/module.modulemap9
-rw-r--r--test/Modules/Inputs/PR27041/Rtypes.h1
-rw-r--r--test/Modules/Inputs/PR27041/TGenericClassInfo.h3
-rw-r--r--test/Modules/Inputs/PR27041/TSchemaHelper.h1
-rw-r--r--test/Modules/Inputs/PR27041/module.modulemap2
-rw-r--r--test/Modules/Inputs/PR27186/Rtypes.h2
-rw-r--r--test/Modules/Inputs/PR27186/module.modulemap5
-rw-r--r--test/Modules/Inputs/PR27186/stddef.h1
-rw-r--r--test/Modules/Inputs/PR27186/time.h1
-rw-r--r--test/Modules/Inputs/PR27401/a.h17
-rw-r--r--test/Modules/Inputs/PR27401/b.h21
-rw-r--r--test/Modules/Inputs/PR27401/module.modulemap1
-rw-r--r--test/Modules/Inputs/PR27513/a.h5
-rw-r--r--test/Modules/Inputs/PR27513/b.h3
-rw-r--r--test/Modules/Inputs/PR27513/b1.h1
-rw-r--r--test/Modules/Inputs/PR27513/b11.h2
-rw-r--r--test/Modules/Inputs/PR27513/b111.h3
-rw-r--r--test/Modules/Inputs/PR27513/b1111.h1
-rw-r--r--test/Modules/Inputs/PR27513/b1112.h1
-rw-r--r--test/Modules/Inputs/PR27513/b2.h1
-rw-r--r--test/Modules/Inputs/PR27513/c.h1
-rw-r--r--test/Modules/Inputs/PR27513/module.modulemap7
-rw-r--r--test/Modules/Inputs/PR27513/mystring.h8
-rw-r--r--test/Modules/Inputs/PR27739/DataInputHandler.h19
-rw-r--r--test/Modules/Inputs/PR27739/Types.h1
-rw-r--r--test/Modules/Inputs/PR27739/map20
-rw-r--r--test/Modules/Inputs/PR27739/module.modulemap2
-rw-r--r--test/Modules/Inputs/PR27754/RConversionRuleParser.h4
-rw-r--r--test/Modules/Inputs/PR27754/TMetaUtils.h2
-rw-r--r--test/Modules/Inputs/PR27754/TSchemaType.h2
-rw-r--r--test/Modules/Inputs/PR27754/algobase.h4
-rw-r--r--test/Modules/Inputs/PR27754/module.modulemap3
-rw-r--r--test/Modules/Inputs/PR27890/a.h9
-rw-r--r--test/Modules/Inputs/PR27890/module.modulemap1
-rw-r--r--test/Modules/Inputs/UseAfterFree/UseAfterFreePrivate.h1
-rw-r--r--test/Modules/Inputs/UseAfterFree/UseAfterFreePublic.h2
-rw-r--r--test/Modules/Inputs/UseAfterFree/module.map3
-rw-r--r--test/Modules/Inputs/UseAfterFree/module_private.map3
-rw-r--r--test/Modules/Inputs/builtin.h4
-rw-r--r--test/Modules/Inputs/category_right.h1
-rw-r--r--test/Modules/Inputs/crash-recovery/Frameworks/A.framework/Headers/A.h1
-rw-r--r--test/Modules/Inputs/crash-recovery/Frameworks/B.framework/Headers/B.h1
-rw-r--r--test/Modules/Inputs/crash-recovery/Frameworks/B.framework/Modules/module.modulemap5
-rw-r--r--test/Modules/Inputs/crash-recovery/Frameworks/I.framework/Headers/I.h2
-rw-r--r--test/Modules/Inputs/crash-recovery/Frameworks/I.framework/Modules/module.modulemap5
-rw-r--r--test/Modules/Inputs/crash-recovery/Frameworks/module.modulemap2
-rw-r--r--test/Modules/Inputs/crash-recovery/usr/include/module.map16
-rw-r--r--test/Modules/Inputs/crash-recovery/usr/include/pthread.h1
-rw-r--r--test/Modules/Inputs/crash-recovery/usr/include/pthread/pthread_impl.h1
-rw-r--r--test/Modules/Inputs/crash-recovery/usr/include/pthread_impl.h1
-rw-r--r--test/Modules/Inputs/crash-recovery/usr/include/stdio.h3
-rw-r--r--test/Modules/Inputs/crash-recovery/usr/include/tcl-private/header.h2
-rw-r--r--test/Modules/Inputs/cxx-decls-imported.h5
-rw-r--r--test/Modules/Inputs/cxx-templates-common.h17
-rw-r--r--test/Modules/Inputs/cxx-templates-unimported.h43
-rw-r--r--test/Modules/Inputs/explicit-build/a.h2
-rw-r--r--test/Modules/Inputs/getSourceDescriptor-crash/h1.h1
-rw-r--r--test/Modules/Inputs/getSourceDescriptor-crash/module.modulemap3
-rw-r--r--test/Modules/Inputs/merge-decl-context/a.h4
-rw-r--r--test/Modules/Inputs/module.map25
-rw-r--r--test/Modules/Inputs/non-module.h4
-rw-r--r--test/Modules/Inputs/pch-import-module-with-macro.pch3
-rw-r--r--test/Modules/Inputs/suggest-include/empty.h0
-rw-r--r--test/Modules/Inputs/suggest-include/module.modulemap22
-rw-r--r--test/Modules/Inputs/suggest-include/private1.h1
-rw-r--r--test/Modules/Inputs/suggest-include/private2.h1
-rw-r--r--test/Modules/Inputs/suggest-include/private3.h1
-rw-r--r--test/Modules/Inputs/suggest-include/textual1.h1
-rw-r--r--test/Modules/Inputs/suggest-include/textual2.h1
-rw-r--r--test/Modules/Inputs/suggest-include/textual3.h1
-rw-r--r--test/Modules/Inputs/suggest-include/textual4.h1
-rw-r--r--test/Modules/Inputs/suggest-include/textual5.h1
-rw-r--r--test/Modules/Inputs/suggest-include/useprivate1.h1
-rw-r--r--test/Modules/Inputs/suggest-include/useprivate3.h1
-rw-r--r--test/Modules/Inputs/suggest-include/usetextual1.h2
-rw-r--r--test/Modules/Inputs/suggest-include/usetextual2.h2
-rw-r--r--test/Modules/Inputs/suggest-include/usetextual3.h1
-rw-r--r--test/Modules/Inputs/suggest-include/usetextual4.h1
-rw-r--r--test/Modules/Inputs/suggest-include/usetextual5.h1
-rw-r--r--test/Modules/Inputs/typo.h6
-rw-r--r--test/Modules/ModuleDebugInfo.cpp100
-rw-r--r--test/Modules/ModuleDebugInfo.m88
-rw-r--r--test/Modules/builtins.m32
-rw-r--r--test/Modules/crash-vfs-path-emptydir-entries.m49
-rw-r--r--test/Modules/crash-vfs-path-symlink-component.m68
-rw-r--r--test/Modules/crash-vfs-path-symlink-topheader.m51
-rw-r--r--test/Modules/crash-vfs-path-traversal.m65
-rw-r--r--test/Modules/crash-vfs-relative-overlay.m61
-rw-r--r--test/Modules/crash-vfs-run-reproducer.m57
-rw-r--r--test/Modules/crash-vfs-umbrella-frameworks.m55
-rw-r--r--test/Modules/cxx-templates.cpp70
-rw-r--r--test/Modules/debug-info-moduleimport.m10
-rw-r--r--test/Modules/embed-files-compressed.cpp23
-rw-r--r--test/Modules/embed-files.cpp8
-rw-r--r--test/Modules/explicit-build-flags.cpp19
-rw-r--r--test/Modules/explicit-build-missing-files.cpp7
-rw-r--r--test/Modules/explicit-build.cpp2
-rw-r--r--test/Modules/getSourceDescriptor-crash.cpp9
-rw-r--r--test/Modules/implementation-of-module.m4
-rw-r--r--test/Modules/implicit-build-config-out-of-date.m6
-rw-r--r--test/Modules/import-self.m2
-rw-r--r--test/Modules/include-own-headers.m4
-rw-r--r--test/Modules/merge-decl-context.cpp8
-rw-r--r--test/Modules/method_pool_write.m11
-rw-r--r--test/Modules/minimal-identifier-tables.cpp10
-rw-r--r--test/Modules/no-implicit-builds.cpp4
-rw-r--r--test/Modules/objc-categories.m2
-rw-r--r--test/Modules/parse-attributes.modulemap12
-rw-r--r--test/Modules/pch-module-macro.m9
-rw-r--r--test/Modules/pr21547.cpp8
-rw-r--r--test/Modules/pr24954.cpp7
-rw-r--r--test/Modules/pr25501.cpp9
-rw-r--r--test/Modules/pr26014.cpp7
-rw-r--r--test/Modules/pr26179.cpp7
-rw-r--r--test/Modules/pr27041.cpp7
-rw-r--r--test/Modules/pr27186.cpp7
-rw-r--r--test/Modules/pr27401.cpp38
-rw-r--r--test/Modules/pr27513.cpp7
-rw-r--r--test/Modules/pr27739.cpp12
-rw-r--r--test/Modules/pr27754.cpp7
-rw-r--r--test/Modules/pr27890.cpp9
-rw-r--r--test/Modules/preprocess.cpp24
-rw-r--r--test/Modules/submodules-merge-defs.cpp7
-rw-r--r--test/Modules/suggest-include.cpp33
-rw-r--r--test/Modules/typo.m8
-rw-r--r--test/Modules/use-after-free.m24
154 files changed, 1773 insertions, 80 deletions
diff --git a/test/Modules/DebugInfoSubmoduleImport.c b/test/Modules/DebugInfoSubmoduleImport.c
index 9fb5d9c6d5c9..1b31aada9c6a 100644
--- a/test/Modules/DebugInfoSubmoduleImport.c
+++ b/test/Modules/DebugInfoSubmoduleImport.c
@@ -1,7 +1,7 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -fmodules -fmodule-format=obj -debug-info-kind=limited -dwarf-ext-refs \
// RUN: -fimplicit-module-maps -x c -fmodules-cache-path=%t -I %S/Inputs \
-// RUN: %s -emit-llvm -o - | FileCheck %s
+// RUN: %s -emit-llvm -debugger-tuning=lldb -o - | FileCheck %s
#include "DebugSubmoduleA.h"
#include "DebugSubmoduleB.h"
diff --git a/test/Modules/DebugInfoTransitiveImport.m b/test/Modules/DebugInfoTransitiveImport.m
index 206be2e42e92..034a909333cd 100644
--- a/test/Modules/DebugInfoTransitiveImport.m
+++ b/test/Modules/DebugInfoTransitiveImport.m
@@ -1,7 +1,7 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -fmodules -fmodule-format=obj -debug-info-kind=limited -dwarf-ext-refs \
// RUN: -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs \
-// RUN: %s -mllvm -debug-only=pchcontainer 2>&1 | FileCheck %s
+// RUN: %s -mllvm -debug-only=pchcontainer -debugger-tuning=lldb 2>&1 | FileCheck %s
// REQUIRES: asserts
@import diamond_left;
@@ -20,3 +20,9 @@
// Skeleton for top:
// CHECK: !DICompileUnit({{.*}}splitDebugFilename: {{.*}}diamond_top{{.*}}dwoId:
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodule-format=obj -debug-info-kind=limited -dwarf-ext-refs \
+// RUN: -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs \
+// RUN: %s -mllvm -debug-only=pchcontainer 2>&1 | FileCheck %s --check-prefix=NOIMPORT
+
+// NOIMPORT-NOT: !DIImportedEntity
diff --git a/test/Modules/ExtDebugInfo.cpp b/test/Modules/ExtDebugInfo.cpp
index b255042cbfec..dbf79f4ff148 100644
--- a/test/Modules/ExtDebugInfo.cpp
+++ b/test/Modules/ExtDebugInfo.cpp
@@ -2,7 +2,8 @@
// Test that only forward declarations are emitted for types dfined in modules.
// Modules:
-// RUN: %clang_cc1 -x objective-c++ -std=c++11 -debug-info-kind=limited -dwarf-ext-refs -fmodules \
+// RUN: %clang_cc1 -x objective-c++ -std=c++11 -debug-info-kind=standalone \
+// RUN: -dwarf-ext-refs -fmodules \
// RUN: -fmodule-format=obj -fimplicit-module-maps -DMODULES \
// RUN: -triple %itanium_abi_triple \
// RUN: -fmodules-cache-path=%t %s -I %S/Inputs -I %t -emit-llvm -o %t-mod.ll
@@ -12,10 +13,12 @@
// RUN: %clang_cc1 -x c++ -std=c++11 -fmodule-format=obj -emit-pch -I%S/Inputs \
// RUN: -triple %itanium_abi_triple \
// RUN: -o %t.pch %S/Inputs/DebugCXX.h
-// RUN: %clang_cc1 -std=c++11 -debug-info-kind=limited -dwarf-ext-refs -fmodule-format=obj \
+// RUN: %clang_cc1 -std=c++11 -debug-info-kind=standalone \
+// RUN: -dwarf-ext-refs -fmodule-format=obj \
// RUN: -triple %itanium_abi_triple \
// RUN: -include-pch %t.pch %s -emit-llvm -o %t-pch.ll %s
// RUN: cat %t-pch.ll | FileCheck %s
+// RUN: cat %t-pch.ll | FileCheck %s --check-prefix=CHECK-PCH
#ifdef MODULES
@import DebugCXX;
@@ -25,9 +28,13 @@ using DebugCXX::Struct;
Struct s;
DebugCXX::Enum e;
+
+// Template instantiations.
DebugCXX::Template<long> implicitTemplate;
DebugCXX::Template<int> explicitTemplate;
-DebugCXX::FloatInstatiation typedefTemplate;
+DebugCXX::FloatInstantiation typedefTemplate;
+DebugCXX::B anchoredTemplate;
+
int Struct::static_member = -1;
enum {
e3 = -1
@@ -35,38 +42,149 @@ enum {
auto anon_enum = DebugCXX::e2;
char _anchor = anon_enum + conflicting_uid;
-// CHECK: ![[NS:.*]] = !DINamespace(name: "DebugCXX", scope: ![[MOD:[0-9]+]],
-// CHECK: ![[MOD]] = !DIModule(scope: null, name: {{.*}}DebugCXX
+TypedefUnion tdu;
+TypedefEnum tde;
+TypedefStruct tds;
+TypedefTemplate tdt;
+Template1<int> explicitTemplate1;
-// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Struct",
-// CHECK-SAME: scope: ![[NS]],
+template <class T> class FwdDeclTemplate { T t; };
+TypedefFwdDeclTemplate tdfdt;
+
+InAnonymousNamespace anon;
+
+// Types that are forward-declared in the module and defined here.
+struct PureFwdDecl { int i; };
+PureFwdDecl definedLocally;
+
+struct Specialized<int>::Member { int i; };
+struct Specialized<int>::Member definedLocally2;
+
+template <class T> struct FwdDeclTemplateMember<T>::Member { T t; };
+TypedefFwdDeclTemplateMember tdfdtm;
+
+void foo() {
+ anon.i = GlobalStruct.i = GlobalUnion.i = GlobalEnum;
+}
+
+
+// CHECK: ![[STRUCT:.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Struct",
+// CHECK-SAME: scope: ![[NS:[0-9]+]],
// CHECK-SAME: flags: DIFlagFwdDecl,
// CHECK-SAME: identifier: "_ZTSN8DebugCXX6StructE")
+// CHECK: ![[NS]] = !DINamespace(name: "DebugCXX", scope: ![[MOD:[0-9]+]],
+// CHECK: ![[MOD]] = !DIModule(scope: null, name: {{.*}}DebugCXX
+
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "Enum",
// CHECK-SAME: scope: ![[NS]],
// CHECK-SAME: flags: DIFlagFwdDecl,
// CHECK-SAME: identifier: "_ZTSN8DebugCXX4EnumE")
+// This type is anchored in the module by an explicit template instantiation.
// CHECK: !DICompositeType(tag: DW_TAG_class_type,
+// CHECK-SAME: name: "Template<long, DebugCXX::traits<long> >",
+// CHECK-SAME: scope: ![[NS]],
+// CHECK-SAME: flags: DIFlagFwdDecl,
+// CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIlNS_6traitsIlEEEE")
+// This type is anchored in the module by an explicit template instantiation.
// CHECK: !DICompositeType(tag: DW_TAG_class_type,
// CHECK-SAME: name: "Template<int, DebugCXX::traits<int> >",
// CHECK-SAME: scope: ![[NS]],
// CHECK-SAME: flags: DIFlagFwdDecl,
// CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIiNS_6traitsIiEEEE")
+// This type isn't, however, even with standalone non-module debug info this
+// type is a forward declaration.
+// CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: "traits<int>",
+
+// This one isn't.
// CHECK: !DICompositeType(tag: DW_TAG_class_type,
// CHECK-SAME: name: "Template<float, DebugCXX::traits<float> >",
// CHECK-SAME: scope: ![[NS]],
-// CHECK-SAME: flags: DIFlagFwdDecl,
+// CHECK-SAME: templateParams:
// CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIfNS_6traitsIfEEEE")
+// This type is anchored in the module by an explicit template instantiation.
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "traits<float>",
+// CHECK-SAME: flags: DIFlagFwdDecl,
+// CHECK-SAME: identifier: "_ZTSN8DebugCXX6traitsIfEE")
+
+
+// This type is anchored in the module by an explicit template instantiation.
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A<void>",
+// CHECK-SAME: scope: ![[NS]],
+// CHECK-SAME: flags: DIFlagFwdDecl,
+// CHECK-SAME: identifier: "_ZTSN8DebugCXX1AIJvEEE")
+
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "static_member",
-// CHECK-SAME: scope: !"_ZTSN8DebugCXX6StructE"
+// CHECK-SAME: scope: ![[STRUCT]]
+
+// CHECK: !DICompositeType(tag: DW_TAG_union_type,
+// CHECK-SAME: flags: DIFlagFwdDecl,
+// CHECK-SAME: identifier: "_ZTS12TypedefUnion")
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type,
+// CHECK-SAME: flags: DIFlagFwdDecl,
+// CHECK-SAME: identifier: "_ZTS11TypedefEnum")
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK-SAME: flags: DIFlagFwdDecl,
+// CHECK-SAME: identifier: "_ZTS13TypedefStruct")
+
+// This one isn't.
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "Template1<void *>",
+// CHECK-SAME: templateParams:
+// CHECK-SAME: identifier: "_ZTS9Template1IPvE")
+
+// This type is anchored in the module by an explicit template instantiation.
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "Template1<int>",
+// CHECK-SAME: flags: DIFlagFwdDecl,
+// CHECK-SAME: identifier: "_ZTS9Template1IiE")
+
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "FwdDeclTemplate<int>",
+// CHECK-SAME: templateParams:
+// CHECK-SAME: identifier: "_ZTS15FwdDeclTemplateIiE")
+
+// This type is defined locally and forward-declared in the module.
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "PureFwdDecl",
+// CHECK-SAME: elements:
+// CHECK-SAME: identifier: "_ZTS11PureFwdDecl")
+
+// This type is defined locally and forward-declared in the module.
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Member",
+// CHECK-SAME: elements:
+// CHECK-SAME: identifier: "_ZTSN11SpecializedIiE6MemberE")
+
+// This type is defined locally and forward-declared in the module.
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Member",
+// CHECK-SAME: elements:
+// CHECK-SAME: identifier: "_ZTSN21FwdDeclTemplateMemberIiE6MemberE")
+
// CHECK: !DIGlobalVariable(name: "anon_enum", {{.*}}, type: ![[ANON_ENUM:[0-9]+]]
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, scope: ![[NS]],
// CHECK-SAME: line: 16
-// CHECK: !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !0, entity: !"_ZTSN8DebugCXX6StructE", line: 24)
+// CHECK: !DIGlobalVariable(name: "GlobalUnion",
+// CHECK-SAME: type: ![[GLOBAL_UNION:[0-9]+]]
+// CHECK: ![[GLOBAL_UNION]] = distinct !DICompositeType(tag: DW_TAG_union_type,
+// CHECK-SAME: elements: !{{[0-9]+}})
+// CHECK: !DIGlobalVariable(name: "GlobalStruct",
+// CHECK-SAME: type: ![[GLOBAL_STRUCT:[0-9]+]]
+// CHECK: ![[GLOBAL_STRUCT]] = distinct !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK-SAME: elements: !{{[0-9]+}})
+
+
+// CHECK: !DIGlobalVariable(name: "anon",
+// CHECK-SAME: type: ![[GLOBAL_ANON:[0-9]+]]
+// CHECK: ![[GLOBAL_ANON]] = !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK-SAME: name: "InAnonymousNamespace", {{.*}}DIFlagFwdDecl)
+
+
+// CHECK: !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !0, entity: ![[STRUCT]], line: 27)
+
+// CHECK: !DICompileUnit(
+// CHECK-SAME: splitDebugFilename:
+// CHECK-SAME: dwoId:
+// CHECK-PCH: !DICompileUnit({{.*}}splitDebugFilename:
+// CHECK-PCH: dwoId: 18446744073709551614
diff --git a/test/Modules/ExtDebugInfo.m b/test/Modules/ExtDebugInfo.m
index 8e063f09048d..71ca853fb7d9 100644
--- a/test/Modules/ExtDebugInfo.m
+++ b/test/Modules/ExtDebugInfo.m
@@ -18,18 +18,59 @@
@import DebugObjC;
#endif
+@implementation ObjCClassWithPrivateIVars {
+ int hidden_ivar;
+}
+@end
+
+TypedefUnion tdu;
+TypedefEnum tde;
+TypedefStruct tds;
+
int foo(ObjCClass *c) {
InnerEnum e = e0;
+ GlobalStruct.i = GlobalUnion.i = GlobalEnum;
[c instanceMethodWithInt: 0];
return [c property];
}
-// CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ObjCClassWithPrivateIVars",
+// CHECK-SAME: flags: DIFlagObjcClassComplete
+
+// CHECK: ![[MOD:.*]] = !DIModule(scope: null, name: "DebugObjC
+
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "hidden_ivar",
+// CHECK-SAME: flags: DIFlagPrivate)
+
+// CHECK: !DIGlobalVariable(name: "GlobalUnion",
+// CHECK-SAME: type: ![[GLOBAL_UNION:[0-9]+]]
+// CHECK: ![[GLOBAL_UNION]] = distinct !DICompositeType(tag: DW_TAG_union_type,
+// CHECK-SAME: elements: !{{[0-9]+}})
+
+// CHECK: !DIGlobalVariable(name: "GlobalStruct",
+// CHECK-SAME: type: ![[GLOBAL_STRUCT:[0-9]+]]
+// CHECK: ![[GLOBAL_STRUCT]] = distinct !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK-SAME: elements: !{{[0-9]+}})
+
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "TypedefUnion",
+// CHECK-SAME: baseType: ![[TD_UNION:.*]])
+// CHECK: ![[TD_UNION]] = !DICompositeType(tag: DW_TAG_union_type,
+// CHECK-SAME: flags: DIFlagFwdDecl)
+
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "TypedefEnum",
+// CHECK-SAME: baseType: ![[TD_ENUM:.*]])
+// CHECK: ![[TD_ENUM]] = !DICompositeType(tag: DW_TAG_enumeration_type,
+// CHECK-SAME: flags: DIFlagFwdDecl)
+
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "TypedefStruct",
+// CHECK-SAME: baseType: ![[TD_STRUCT:.*]])
+// CHECK: ![[TD_STRUCT]] = !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK-SAME: flags: DIFlagFwdDecl)
+
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ObjCClass",
-// CHECK-SAME: scope: ![[MOD:[0-9]+]],
+// CHECK-SAME: scope: ![[MOD]],
// CHECK-SAME: flags: DIFlagFwdDecl)
-// CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type,
-// CHECK: ![[MOD]] = !DIModule(scope: null, name: {{.*}}DebugObjC
+
// CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type,
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type,
// CHECK-SAME: scope: ![[MOD]],
diff --git a/test/Modules/Inputs/DebugCXX.h b/test/Modules/Inputs/DebugCXX.h
index b6a52579fc3a..793ad209f8bf 100644
--- a/test/Modules/Inputs/DebugCXX.h
+++ b/test/Modules/Inputs/DebugCXX.h
@@ -24,10 +24,11 @@ namespace DebugCXX {
> class Template {
T member;
};
+ // Explicit template instantiation.
extern template class Template<int>;
extern template struct traits<float>;
- typedef class Template<float> FloatInstatiation;
+ typedef class Template<float> FloatInstantiation;
inline void fn() {
Template<long> invisible;
@@ -48,6 +49,7 @@ namespace DebugCXX {
template <typename...> class A;
template <typename T> class A<T> {};
typedef A<void> B;
+ // Anchored by a function parameter.
void foo(B) {}
}
@@ -58,3 +60,48 @@ class FwdVirtual {
};
struct PureForwardDecl;
+
+typedef union { int i; } TypedefUnion;
+typedef enum { e0 = 0 } TypedefEnum;
+typedef struct { int i; } TypedefStruct;
+
+union { int i; } GlobalUnion;
+struct { int i; } GlobalStruct;
+enum { e5 = 5 } GlobalEnum;
+
+namespace {
+ namespace {
+ struct InAnonymousNamespace { int i; };
+ }
+}
+
+class Base;
+class A {
+ virtual Base *getParent() const;
+};
+class Base {};
+class Derived : Base {
+ class B : A {
+ Derived *getParent() const override;
+ };
+};
+
+template <class T>
+class Template1 {
+ T t;
+};
+typedef Template1<void *> TypedefTemplate;
+extern template class Template1<int>;
+
+template <class T> class FwdDeclTemplate;
+typedef FwdDeclTemplate<int> TypedefFwdDeclTemplate;
+
+// Member classes of class template specializations.
+template <typename T> struct Specialized {};
+
+template <> struct Specialized<int> {
+ struct Member;
+};
+
+template <class T> struct FwdDeclTemplateMember { struct Member; };
+typedef FwdDeclTemplateMember<int>::Member TypedefFwdDeclTemplateMember;
diff --git a/test/Modules/Inputs/DebugObjC.h b/test/Modules/Inputs/DebugObjC.h
index bde463abfd61..af1cd981ce1c 100644
--- a/test/Modules/Inputs/DebugObjC.h
+++ b/test/Modules/Inputs/DebugObjC.h
@@ -1,3 +1,4 @@
+// -*- ObjC -*-
@class FwdDecl;
@interface ObjCClass {
@@ -9,6 +10,11 @@
@property int property;
@end
+@interface ObjCClassWithPrivateIVars {
+ int public_ivar;
+}
+@end
+
@interface ObjCClass (Category)
- categoryMethod;
@end
@@ -22,3 +28,17 @@ typedef enum {
+ (InnerEnum)protocolMethod;
@end
+
+struct FwdDeclared;
+struct FwdDeclared {
+ int i;
+};
+struct PureForwardDecl;
+
+typedef union { int i; } TypedefUnion;
+typedef enum { e1 = 1 } TypedefEnum;
+typedef struct { int i; } TypedefStruct;
+
+union { int i; } GlobalUnion;
+struct { int i; } GlobalStruct;
+enum { e2 = 2 } GlobalEnum;
diff --git a/test/Modules/Inputs/MacroFabs1.h b/test/Modules/Inputs/MacroFabs1.h
new file mode 100644
index 000000000000..a78c5539f4a2
--- /dev/null
+++ b/test/Modules/Inputs/MacroFabs1.h
@@ -0,0 +1,6 @@
+
+#undef fabs
+#define fabs(x) (x)
+
+#undef my_fabs
+#define my_fabs(x) (x)
diff --git a/test/Modules/Inputs/MethodPoolCombined1.h b/test/Modules/Inputs/MethodPoolCombined1.h
new file mode 100644
index 000000000000..057b7388b35f
--- /dev/null
+++ b/test/Modules/Inputs/MethodPoolCombined1.h
@@ -0,0 +1,6 @@
+
+@import MethodPoolString1;
+@interface A
+- (int)stringValue;
+@end
+
diff --git a/test/Modules/Inputs/MethodPoolCombined2.h b/test/Modules/Inputs/MethodPoolCombined2.h
new file mode 100644
index 000000000000..166906e32e39
--- /dev/null
+++ b/test/Modules/Inputs/MethodPoolCombined2.h
@@ -0,0 +1 @@
+@import MethodPoolString2;
diff --git a/test/Modules/Inputs/MethodPoolString1.h b/test/Modules/Inputs/MethodPoolString1.h
new file mode 100644
index 000000000000..c64ad950033e
--- /dev/null
+++ b/test/Modules/Inputs/MethodPoolString1.h
@@ -0,0 +1,4 @@
+
+@interface S1
+- (int)stringValue;
+@end
diff --git a/test/Modules/Inputs/MethodPoolString2.h b/test/Modules/Inputs/MethodPoolString2.h
new file mode 100644
index 000000000000..30e9bfb0027d
--- /dev/null
+++ b/test/Modules/Inputs/MethodPoolString2.h
@@ -0,0 +1,4 @@
+
+@interface S2
+- (int)stringValue;
+@end
diff --git a/test/Modules/Inputs/PR21547/FirstHeader.h b/test/Modules/Inputs/PR21547/FirstHeader.h
new file mode 100644
index 000000000000..a01c6075932f
--- /dev/null
+++ b/test/Modules/Inputs/PR21547/FirstHeader.h
@@ -0,0 +1,13 @@
+template<class Element> struct TMatrixT;
+typedef TMatrixT<double> TMatrixD;
+
+void f(const TMatrixD &m);
+
+template<class Element> struct TMatrixT {
+ template <class Element2> TMatrixT(const TMatrixT<Element2> &);
+ ~TMatrixT() {}
+ void Determinant () { f(*this); }
+};
+
+template struct TMatrixT<float>;
+template struct TMatrixT<double>;
diff --git a/test/Modules/Inputs/PR21547/module.modulemap b/test/Modules/Inputs/PR21547/module.modulemap
new file mode 100644
index 000000000000..8ca0643888b8
--- /dev/null
+++ b/test/Modules/Inputs/PR21547/module.modulemap
@@ -0,0 +1,4 @@
+module M {
+ header "FirstHeader.h"
+ export *
+}
diff --git a/test/Modules/Inputs/PR24954/A.h b/test/Modules/Inputs/PR24954/A.h
new file mode 100644
index 000000000000..5e5d5bf92ce4
--- /dev/null
+++ b/test/Modules/Inputs/PR24954/A.h
@@ -0,0 +1,10 @@
+#include "B.h"
+
+template <class T>
+class Expr {
+public:
+ void print(B::basic_ostream<char>& os) {
+ os << B::setw(42);
+ os << B::endl;
+ }
+};
diff --git a/test/Modules/Inputs/PR24954/B.h b/test/Modules/Inputs/PR24954/B.h
new file mode 100644
index 000000000000..a8ddc7189270
--- /dev/null
+++ b/test/Modules/Inputs/PR24954/B.h
@@ -0,0 +1,30 @@
+namespace B {
+
+ template <class _CharT>
+ struct basic_ostream {
+ basic_ostream& operator<<(basic_ostream& (*__pf)());
+ };
+
+
+ template <class _CharT> basic_ostream<_CharT>&
+ endl();
+
+ struct S1 {
+ template <class _CharT> friend void
+ operator<<(basic_ostream<_CharT>& __os, const S1& __x);
+ };
+
+ S1 setw(int __n);
+
+ template <class _CharT> class S2;
+
+ template <class _CharT> void
+ operator<<(basic_ostream<_CharT>& __os, const S2<_CharT>& __x);
+
+ template <class _CharT>
+ struct S2 {
+ template <class _Cp> friend void
+ operator<<(basic_ostream<_Cp>& __os, const S2<_Cp>& __x);
+ };
+
+}
diff --git a/test/Modules/Inputs/PR24954/module.modulemap b/test/Modules/Inputs/PR24954/module.modulemap
new file mode 100644
index 000000000000..49374181d758
--- /dev/null
+++ b/test/Modules/Inputs/PR24954/module.modulemap
@@ -0,0 +1,9 @@
+module A {
+ header "A.h"
+ export *
+}
+
+module B {
+ header "B.h"
+ export *
+}
diff --git a/test/Modules/Inputs/PR25501/Vector.h b/test/Modules/Inputs/PR25501/Vector.h
new file mode 100644
index 000000000000..9da48303a3a8
--- /dev/null
+++ b/test/Modules/Inputs/PR25501/Vector.h
@@ -0,0 +1,5 @@
+template <typename> struct _Vector_base {};
+struct vector {
+ vector() {}
+ vector(_Vector_base<int>);
+};
diff --git a/test/Modules/Inputs/PR25501/a0.h b/test/Modules/Inputs/PR25501/a0.h
new file mode 100644
index 000000000000..1a0d306ca7cf
--- /dev/null
+++ b/test/Modules/Inputs/PR25501/a0.h
@@ -0,0 +1 @@
+#include "Vector.h"
diff --git a/test/Modules/Inputs/PR25501/a1.h b/test/Modules/Inputs/PR25501/a1.h
new file mode 100644
index 000000000000..1a0d306ca7cf
--- /dev/null
+++ b/test/Modules/Inputs/PR25501/a1.h
@@ -0,0 +1 @@
+#include "Vector.h"
diff --git a/test/Modules/Inputs/PR25501/a2.h b/test/Modules/Inputs/PR25501/a2.h
new file mode 100644
index 000000000000..7876f310e85f
--- /dev/null
+++ b/test/Modules/Inputs/PR25501/a2.h
@@ -0,0 +1,3 @@
+#include "a0.h"
+vector aaa = vector();
+#include "a1.h"
diff --git a/test/Modules/Inputs/PR25501/b.h b/test/Modules/Inputs/PR25501/b.h
new file mode 100644
index 000000000000..7b519836953a
--- /dev/null
+++ b/test/Modules/Inputs/PR25501/b.h
@@ -0,0 +1,2 @@
+#include "Vector.h"
+vector aaa = vector();
diff --git a/test/Modules/Inputs/PR25501/module.modulemap b/test/Modules/Inputs/PR25501/module.modulemap
new file mode 100644
index 000000000000..c6c8d5ca40f3
--- /dev/null
+++ b/test/Modules/Inputs/PR25501/module.modulemap
@@ -0,0 +1,4 @@
+module "a0" { header "a0.h" export * }
+module "a1" { header "a1.h" export * }
+module "a2" { header "a2.h" export * }
+module "b" { header "b.h" export * }
diff --git a/test/Modules/Inputs/PR26014/A.h b/test/Modules/Inputs/PR26014/A.h
new file mode 100644
index 000000000000..49de5ba479af
--- /dev/null
+++ b/test/Modules/Inputs/PR26014/A.h
@@ -0,0 +1,13 @@
+#ifndef _LIBCPP_TYPE_TRAITS
+#define _LIBCPP_TYPE_TRAITS
+
+
+template <class _Tp>
+struct underlying_type
+{
+ typedef __underlying_type(_Tp) type;
+};
+
+#endif // _LIBCPP_TYPE_TRAITS
+
+#include "B.h"
diff --git a/test/Modules/Inputs/PR26014/B.h b/test/Modules/Inputs/PR26014/B.h
new file mode 100644
index 000000000000..58d1f8ff2a3f
--- /dev/null
+++ b/test/Modules/Inputs/PR26014/B.h
@@ -0,0 +1,10 @@
+#ifndef _LIBCPP_TYPE_TRAITS
+#define _LIBCPP_TYPE_TRAITS
+
+template <class _Tp>
+struct underlying_type
+{
+ typedef __underlying_type(_Tp) type;
+};
+
+#endif // _LIBCPP_TYPE_TRAITS
diff --git a/test/Modules/Inputs/PR26014/module.modulemap b/test/Modules/Inputs/PR26014/module.modulemap
new file mode 100644
index 000000000000..49374181d758
--- /dev/null
+++ b/test/Modules/Inputs/PR26014/module.modulemap
@@ -0,0 +1,9 @@
+module A {
+ header "A.h"
+ export *
+}
+
+module B {
+ header "B.h"
+ export *
+}
diff --git a/test/Modules/Inputs/PR26179/A.h b/test/Modules/Inputs/PR26179/A.h
new file mode 100644
index 000000000000..c264f4cf9bfb
--- /dev/null
+++ b/test/Modules/Inputs/PR26179/A.h
@@ -0,0 +1,2 @@
+#include "basic_string.h"
+#include "B.h"
diff --git a/test/Modules/Inputs/PR26179/B.h b/test/Modules/Inputs/PR26179/B.h
new file mode 100644
index 000000000000..46a109efdb59
--- /dev/null
+++ b/test/Modules/Inputs/PR26179/B.h
@@ -0,0 +1 @@
+#include "basic_string.h"
diff --git a/test/Modules/Inputs/PR26179/basic_string.h b/test/Modules/Inputs/PR26179/basic_string.h
new file mode 100644
index 000000000000..653ce078451c
--- /dev/null
+++ b/test/Modules/Inputs/PR26179/basic_string.h
@@ -0,0 +1,12 @@
+#ifndef _GLIBCXX_STRING
+#define _GLIBCXX_STRING 1
+
+template<typename T>
+struct basic_string {
+ static T _S_empty_rep_storage[];
+};
+
+template<typename T>
+T basic_string<T>::_S_empty_rep_storage[sizeof(T)];
+
+#endif
diff --git a/test/Modules/Inputs/PR26179/module.modulemap b/test/Modules/Inputs/PR26179/module.modulemap
new file mode 100644
index 000000000000..49374181d758
--- /dev/null
+++ b/test/Modules/Inputs/PR26179/module.modulemap
@@ -0,0 +1,9 @@
+module A {
+ header "A.h"
+ export *
+}
+
+module B {
+ header "B.h"
+ export *
+}
diff --git a/test/Modules/Inputs/PR27041/Rtypes.h b/test/Modules/Inputs/PR27041/Rtypes.h
new file mode 100644
index 000000000000..8b137891791f
--- /dev/null
+++ b/test/Modules/Inputs/PR27041/Rtypes.h
@@ -0,0 +1 @@
+
diff --git a/test/Modules/Inputs/PR27041/TGenericClassInfo.h b/test/Modules/Inputs/PR27041/TGenericClassInfo.h
new file mode 100644
index 000000000000..b43b2c90f22b
--- /dev/null
+++ b/test/Modules/Inputs/PR27041/TGenericClassInfo.h
@@ -0,0 +1,3 @@
+namespace std {}
+namespace std { enum float_round_style { denorm_present }; }
+#include "TSchemaHelper.h"
diff --git a/test/Modules/Inputs/PR27041/TSchemaHelper.h b/test/Modules/Inputs/PR27041/TSchemaHelper.h
new file mode 100644
index 000000000000..31f726f4d75f
--- /dev/null
+++ b/test/Modules/Inputs/PR27041/TSchemaHelper.h
@@ -0,0 +1 @@
+namespace std { enum float_round_style { denorm_present }; }
diff --git a/test/Modules/Inputs/PR27041/module.modulemap b/test/Modules/Inputs/PR27041/module.modulemap
new file mode 100644
index 000000000000..f0147cdf9762
--- /dev/null
+++ b/test/Modules/Inputs/PR27041/module.modulemap
@@ -0,0 +1,2 @@
+module "Rtypes.h" { header "Rtypes.h" header "TGenericClassInfo.h" }
+module "TSchemaHelper.h" { header "TSchemaHelper.h" }
diff --git a/test/Modules/Inputs/PR27186/Rtypes.h b/test/Modules/Inputs/PR27186/Rtypes.h
new file mode 100644
index 000000000000..ecbe10d34d29
--- /dev/null
+++ b/test/Modules/Inputs/PR27186/Rtypes.h
@@ -0,0 +1,2 @@
+#include <stddef.h>
+typedef struct timespec timespec_t;
diff --git a/test/Modules/Inputs/PR27186/module.modulemap b/test/Modules/Inputs/PR27186/module.modulemap
new file mode 100644
index 000000000000..58ce19d0d55c
--- /dev/null
+++ b/test/Modules/Inputs/PR27186/module.modulemap
@@ -0,0 +1,5 @@
+module "Rtypes.h" { header "Rtypes.h" }
+module a [extern_c] {
+ header "stddef.h"
+ header "time.h"
+}
diff --git a/test/Modules/Inputs/PR27186/stddef.h b/test/Modules/Inputs/PR27186/stddef.h
new file mode 100644
index 000000000000..8b137891791f
--- /dev/null
+++ b/test/Modules/Inputs/PR27186/stddef.h
@@ -0,0 +1 @@
+
diff --git a/test/Modules/Inputs/PR27186/time.h b/test/Modules/Inputs/PR27186/time.h
new file mode 100644
index 000000000000..9ac2ace3734b
--- /dev/null
+++ b/test/Modules/Inputs/PR27186/time.h
@@ -0,0 +1 @@
+struct timespec;
diff --git a/test/Modules/Inputs/PR27401/a.h b/test/Modules/Inputs/PR27401/a.h
new file mode 100644
index 000000000000..63d6b707f46f
--- /dev/null
+++ b/test/Modules/Inputs/PR27401/a.h
@@ -0,0 +1,17 @@
+#ifndef _LIBCPP_ALGORITHM
+#define _LIBCPP_ALGORITHM
+template <class _Tp, _Tp>
+struct integral_constant {
+ static const _Tp value = _Tp();
+};
+
+template <class _Tp>
+struct is_nothrow_default_constructible
+ : integral_constant<bool, __is_constructible(_Tp)> {};
+
+template <class _Tp>
+struct is_nothrow_move_constructible
+ : integral_constant<bool, __is_constructible(_Tp, _Tp)> {};
+
+class allocator {};
+#endif
diff --git a/test/Modules/Inputs/PR27401/b.h b/test/Modules/Inputs/PR27401/b.h
new file mode 100644
index 000000000000..2b4e7f14fbb4
--- /dev/null
+++ b/test/Modules/Inputs/PR27401/b.h
@@ -0,0 +1,21 @@
+#include "a.h"
+#ifndef _LIBCPP_VECTOR
+template <class, class _Allocator>
+class __vector_base {
+protected:
+ _Allocator __alloc() const;
+ __vector_base(_Allocator);
+};
+
+template <class _Tp, class _Allocator = allocator>
+class vector : __vector_base<_Tp, _Allocator> {
+public:
+ vector() noexcept(is_nothrow_default_constructible<_Allocator>::value);
+ vector(const vector &);
+ vector(vector &&)
+ noexcept(is_nothrow_move_constructible<_Allocator>::value);
+};
+
+#endif
+void GetUniquePtrType() { vector<char> v; }
+
diff --git a/test/Modules/Inputs/PR27401/module.modulemap b/test/Modules/Inputs/PR27401/module.modulemap
new file mode 100644
index 000000000000..a0efadaa0eaf
--- /dev/null
+++ b/test/Modules/Inputs/PR27401/module.modulemap
@@ -0,0 +1 @@
+module "b" { header "b.h" export * }
diff --git a/test/Modules/Inputs/PR27513/a.h b/test/Modules/Inputs/PR27513/a.h
new file mode 100644
index 000000000000..7eecbf4773d8
--- /dev/null
+++ b/test/Modules/Inputs/PR27513/a.h
@@ -0,0 +1,5 @@
+#include "b.h"
+
+inline void f() { basic_string<char> s; }
+
+#include "c.h"
diff --git a/test/Modules/Inputs/PR27513/b.h b/test/Modules/Inputs/PR27513/b.h
new file mode 100644
index 000000000000..b514c1e3476a
--- /dev/null
+++ b/test/Modules/Inputs/PR27513/b.h
@@ -0,0 +1,3 @@
+#include "mystring.h"
+#include "b1.h"
+#include "b2.h"
diff --git a/test/Modules/Inputs/PR27513/b1.h b/test/Modules/Inputs/PR27513/b1.h
new file mode 100644
index 000000000000..a12b29f71bf9
--- /dev/null
+++ b/test/Modules/Inputs/PR27513/b1.h
@@ -0,0 +1 @@
+#include "b11.h"
diff --git a/test/Modules/Inputs/PR27513/b11.h b/test/Modules/Inputs/PR27513/b11.h
new file mode 100644
index 000000000000..e7bfaec9ce7c
--- /dev/null
+++ b/test/Modules/Inputs/PR27513/b11.h
@@ -0,0 +1,2 @@
+#include "mystring.h"
+#include "b111.h"
diff --git a/test/Modules/Inputs/PR27513/b111.h b/test/Modules/Inputs/PR27513/b111.h
new file mode 100644
index 000000000000..b7a63b5c2324
--- /dev/null
+++ b/test/Modules/Inputs/PR27513/b111.h
@@ -0,0 +1,3 @@
+#include "mystring.h"
+#include "b1111.h"
+#include "b1112.h"
diff --git a/test/Modules/Inputs/PR27513/b1111.h b/test/Modules/Inputs/PR27513/b1111.h
new file mode 100644
index 000000000000..3f9cf449b379
--- /dev/null
+++ b/test/Modules/Inputs/PR27513/b1111.h
@@ -0,0 +1 @@
+#include "mystring.h"
diff --git a/test/Modules/Inputs/PR27513/b1112.h b/test/Modules/Inputs/PR27513/b1112.h
new file mode 100644
index 000000000000..3f9cf449b379
--- /dev/null
+++ b/test/Modules/Inputs/PR27513/b1112.h
@@ -0,0 +1 @@
+#include "mystring.h"
diff --git a/test/Modules/Inputs/PR27513/b2.h b/test/Modules/Inputs/PR27513/b2.h
new file mode 100644
index 000000000000..3f9cf449b379
--- /dev/null
+++ b/test/Modules/Inputs/PR27513/b2.h
@@ -0,0 +1 @@
+#include "mystring.h"
diff --git a/test/Modules/Inputs/PR27513/c.h b/test/Modules/Inputs/PR27513/c.h
new file mode 100644
index 000000000000..3f9cf449b379
--- /dev/null
+++ b/test/Modules/Inputs/PR27513/c.h
@@ -0,0 +1 @@
+#include "mystring.h"
diff --git a/test/Modules/Inputs/PR27513/module.modulemap b/test/Modules/Inputs/PR27513/module.modulemap
new file mode 100644
index 000000000000..ee2a9ce4aa58
--- /dev/null
+++ b/test/Modules/Inputs/PR27513/module.modulemap
@@ -0,0 +1,7 @@
+module "c.h" {header "c.h" export *}
+module "b2.h" { header "b2.h" export *}
+module "b.h" {header "b.h" export *}
+module "b111.h" { header "b111.h" export *}
+module "b11.h" { header "b11.h" export *}
+module "b1111.h" { header "b1111.h" export *}
+module "b1112.h" { header "b1112.h" export *}
diff --git a/test/Modules/Inputs/PR27513/mystring.h b/test/Modules/Inputs/PR27513/mystring.h
new file mode 100644
index 000000000000..95680ed8837b
--- /dev/null
+++ b/test/Modules/Inputs/PR27513/mystring.h
@@ -0,0 +1,8 @@
+#ifndef _GLIBCXX_STRING
+#define _GLIBCXX_STRING
+template<typename> struct basic_string {
+ struct _Alloc_hider {} _M_dataplus;
+ ~basic_string() { _Alloc_hider h; }
+};
+extern template class basic_string<char>;
+#endif
diff --git a/test/Modules/Inputs/PR27739/DataInputHandler.h b/test/Modules/Inputs/PR27739/DataInputHandler.h
new file mode 100644
index 000000000000..1ef02ecb8da0
--- /dev/null
+++ b/test/Modules/Inputs/PR27739/DataInputHandler.h
@@ -0,0 +1,19 @@
+template < typename > struct vector {};
+
+#include <map>
+#include "Types.h"
+
+struct TString {
+ TString (char *);
+};
+
+struct TreeInfo {};
+
+class DataInputHandler {
+ void AddTree ();
+ void SignalTreeInfo () {
+ fInputTrees[(char*)""];
+ }
+ map <TString, vector <TreeInfo> >fInputTrees;
+ map <string, bool> fExplicitTrainTest;
+};
diff --git a/test/Modules/Inputs/PR27739/Types.h b/test/Modules/Inputs/PR27739/Types.h
new file mode 100644
index 000000000000..6d458a8d9826
--- /dev/null
+++ b/test/Modules/Inputs/PR27739/Types.h
@@ -0,0 +1 @@
+#include <map>
diff --git a/test/Modules/Inputs/PR27739/map b/test/Modules/Inputs/PR27739/map
new file mode 100644
index 000000000000..612685c9e5bd
--- /dev/null
+++ b/test/Modules/Inputs/PR27739/map
@@ -0,0 +1,20 @@
+#ifndef _GLIBCXX_MAP
+#define _GLIBCXX_MAP
+struct basic_string {
+ basic_string(char *);
+} typedef string;
+
+template <typename> class D;
+template <typename _Elements> struct D {
+ _Elements _M_;
+ D(D &) = default;
+};
+
+template <typename _Elements> D<_Elements &&> forward_as_tuple(_Elements);
+
+template <typename _Key, typename _Tp> struct map {
+ _Tp operator[](_Key p1) {
+ auto b = &forward_as_tuple(p1);
+ }
+};
+#endif
diff --git a/test/Modules/Inputs/PR27739/module.modulemap b/test/Modules/Inputs/PR27739/module.modulemap
new file mode 100644
index 000000000000..d611e8079e51
--- /dev/null
+++ b/test/Modules/Inputs/PR27739/module.modulemap
@@ -0,0 +1,2 @@
+module "DataInputHandler.h" { header "DataInputHandler.h" export * }
+module "Types.h" { header "Types.h" export *}
diff --git a/test/Modules/Inputs/PR27754/RConversionRuleParser.h b/test/Modules/Inputs/PR27754/RConversionRuleParser.h
new file mode 100644
index 000000000000..057dd14698a9
--- /dev/null
+++ b/test/Modules/Inputs/PR27754/RConversionRuleParser.h
@@ -0,0 +1,4 @@
+#include "algobase.h"
+typedef integral_constant<bool, true> true_type;
+class _Rb_tree { _Rb_tree() { true_type(); } };
+#include "TSchemaType.h"
diff --git a/test/Modules/Inputs/PR27754/TMetaUtils.h b/test/Modules/Inputs/PR27754/TMetaUtils.h
new file mode 100644
index 000000000000..835b7c6dc607
--- /dev/null
+++ b/test/Modules/Inputs/PR27754/TMetaUtils.h
@@ -0,0 +1,2 @@
+#include "RConversionRuleParser.h"
+void fn1() { true_type(); }
diff --git a/test/Modules/Inputs/PR27754/TSchemaType.h b/test/Modules/Inputs/PR27754/TSchemaType.h
new file mode 100644
index 000000000000..2c477931707b
--- /dev/null
+++ b/test/Modules/Inputs/PR27754/TSchemaType.h
@@ -0,0 +1,2 @@
+#include "algobase.h"
+struct A : integral_constant<bool, true> {};
diff --git a/test/Modules/Inputs/PR27754/algobase.h b/test/Modules/Inputs/PR27754/algobase.h
new file mode 100644
index 000000000000..f5e47d8dc7d3
--- /dev/null
+++ b/test/Modules/Inputs/PR27754/algobase.h
@@ -0,0 +1,4 @@
+#ifndef _STL_ALGOBASE_H
+#define _STL_ALGOBASE_H
+template<typename _Tp, _Tp> struct integral_constant {};
+#endif
diff --git a/test/Modules/Inputs/PR27754/module.modulemap b/test/Modules/Inputs/PR27754/module.modulemap
new file mode 100644
index 000000000000..90dcdbb92b4e
--- /dev/null
+++ b/test/Modules/Inputs/PR27754/module.modulemap
@@ -0,0 +1,3 @@
+module "RConversionRuleParser.h" { header "RConversionRuleParser.h" }
+module "TMetaUtils.h" { header "TMetaUtils.h" }
+module "TSchemaType.h" { header "TSchemaType.h" }
diff --git a/test/Modules/Inputs/PR27890/a.h b/test/Modules/Inputs/PR27890/a.h
new file mode 100644
index 000000000000..9c6e56211600
--- /dev/null
+++ b/test/Modules/Inputs/PR27890/a.h
@@ -0,0 +1,9 @@
+template <class DataType> DataType values(DataType) { __builtin_va_list ValueArgs; return DataType(); }
+
+template <class DataType>
+class opt {
+public:
+ template <class Mods>
+ opt(Mods) {}
+};
+
diff --git a/test/Modules/Inputs/PR27890/module.modulemap b/test/Modules/Inputs/PR27890/module.modulemap
new file mode 100644
index 000000000000..85074e807897
--- /dev/null
+++ b/test/Modules/Inputs/PR27890/module.modulemap
@@ -0,0 +1 @@
+module A { header "a.h" export * }
diff --git a/test/Modules/Inputs/UseAfterFree/UseAfterFreePrivate.h b/test/Modules/Inputs/UseAfterFree/UseAfterFreePrivate.h
new file mode 100644
index 000000000000..e8ed9fda5874
--- /dev/null
+++ b/test/Modules/Inputs/UseAfterFree/UseAfterFreePrivate.h
@@ -0,0 +1 @@
+@import UseAfterFreePublic;
diff --git a/test/Modules/Inputs/UseAfterFree/UseAfterFreePublic.h b/test/Modules/Inputs/UseAfterFree/UseAfterFreePublic.h
new file mode 100644
index 000000000000..d017b0f310b4
--- /dev/null
+++ b/test/Modules/Inputs/UseAfterFree/UseAfterFreePublic.h
@@ -0,0 +1,2 @@
+@interface S1
+@end
diff --git a/test/Modules/Inputs/UseAfterFree/module.map b/test/Modules/Inputs/UseAfterFree/module.map
new file mode 100644
index 000000000000..35c0b3d230d5
--- /dev/null
+++ b/test/Modules/Inputs/UseAfterFree/module.map
@@ -0,0 +1,3 @@
+module UseAfterFreePublic {
+ header "UseAfterFreePublic.h"
+}
diff --git a/test/Modules/Inputs/UseAfterFree/module_private.map b/test/Modules/Inputs/UseAfterFree/module_private.map
new file mode 100644
index 000000000000..75eec4162c4e
--- /dev/null
+++ b/test/Modules/Inputs/UseAfterFree/module_private.map
@@ -0,0 +1,3 @@
+module UseAfterFreePrivate {
+ header "UseAfterFreePrivate.h"
+}
diff --git a/test/Modules/Inputs/builtin.h b/test/Modules/Inputs/builtin.h
index 7be90177d194..4717ff2a52a2 100644
--- a/test/Modules/Inputs/builtin.h
+++ b/test/Modules/Inputs/builtin.h
@@ -1,3 +1,7 @@
int i;
int *p = &i;
+void use_constant_string_builtins(void) {
+ (void)__builtin___CFStringMakeConstantString("");
+ (void)__builtin___NSStringMakeConstantString("");
+}
diff --git a/test/Modules/Inputs/category_right.h b/test/Modules/Inputs/category_right.h
index 3c83624c7616..d8dedf888d15 100644
--- a/test/Modules/Inputs/category_right.h
+++ b/test/Modules/Inputs/category_right.h
@@ -1,4 +1,5 @@
@import category_top;
+#import "category_right_sub.h"
@interface Foo(Right1)
-(void)right1;
diff --git a/test/Modules/Inputs/crash-recovery/Frameworks/A.framework/Headers/A.h b/test/Modules/Inputs/crash-recovery/Frameworks/A.framework/Headers/A.h
new file mode 100644
index 000000000000..49c9fe07531d
--- /dev/null
+++ b/test/Modules/Inputs/crash-recovery/Frameworks/A.framework/Headers/A.h
@@ -0,0 +1 @@
+#include <B/B.h>
diff --git a/test/Modules/Inputs/crash-recovery/Frameworks/B.framework/Headers/B.h b/test/Modules/Inputs/crash-recovery/Frameworks/B.framework/Headers/B.h
new file mode 100644
index 000000000000..761540b09cb3
--- /dev/null
+++ b/test/Modules/Inputs/crash-recovery/Frameworks/B.framework/Headers/B.h
@@ -0,0 +1 @@
+// B.h
diff --git a/test/Modules/Inputs/crash-recovery/Frameworks/B.framework/Modules/module.modulemap b/test/Modules/Inputs/crash-recovery/Frameworks/B.framework/Modules/module.modulemap
new file mode 100644
index 000000000000..f6c6e7bf6681
--- /dev/null
+++ b/test/Modules/Inputs/crash-recovery/Frameworks/B.framework/Modules/module.modulemap
@@ -0,0 +1,5 @@
+framework module B [extern_c] {
+ umbrella header "B.h"
+ export *
+ module * { export * }
+}
diff --git a/test/Modules/Inputs/crash-recovery/Frameworks/I.framework/Headers/I.h b/test/Modules/Inputs/crash-recovery/Frameworks/I.framework/Headers/I.h
new file mode 100644
index 000000000000..f98baaa7bd3f
--- /dev/null
+++ b/test/Modules/Inputs/crash-recovery/Frameworks/I.framework/Headers/I.h
@@ -0,0 +1,2 @@
+
+#import <A/A.h>
diff --git a/test/Modules/Inputs/crash-recovery/Frameworks/I.framework/Modules/module.modulemap b/test/Modules/Inputs/crash-recovery/Frameworks/I.framework/Modules/module.modulemap
new file mode 100644
index 000000000000..912d39ecf3be
--- /dev/null
+++ b/test/Modules/Inputs/crash-recovery/Frameworks/I.framework/Modules/module.modulemap
@@ -0,0 +1,5 @@
+framework module I [extern_c] {
+ umbrella header "I.h"
+ export *
+ module * { export * }
+}
diff --git a/test/Modules/Inputs/crash-recovery/Frameworks/module.modulemap b/test/Modules/Inputs/crash-recovery/Frameworks/module.modulemap
new file mode 100644
index 000000000000..0f6fcc0b5ada
--- /dev/null
+++ b/test/Modules/Inputs/crash-recovery/Frameworks/module.modulemap
@@ -0,0 +1,2 @@
+framework module * [extern_c] {
+}
diff --git a/test/Modules/Inputs/crash-recovery/usr/include/module.map b/test/Modules/Inputs/crash-recovery/usr/include/module.map
new file mode 100644
index 000000000000..9b429160db50
--- /dev/null
+++ b/test/Modules/Inputs/crash-recovery/usr/include/module.map
@@ -0,0 +1,16 @@
+module cstd [system] {
+ // Only in system headers directory
+ module stdio {
+ header "stdio.h"
+ }
+
+ module pthread {
+ header "pthread.h"
+ export *
+
+ module impl {
+ header "pthread_impl.h"
+ export *
+ }
+ }
+}
diff --git a/test/Modules/Inputs/crash-recovery/usr/include/pthread.h b/test/Modules/Inputs/crash-recovery/usr/include/pthread.h
new file mode 100644
index 000000000000..44ac9fce9520
--- /dev/null
+++ b/test/Modules/Inputs/crash-recovery/usr/include/pthread.h
@@ -0,0 +1 @@
+#include "pthread/pthread_impl.h"
diff --git a/test/Modules/Inputs/crash-recovery/usr/include/pthread/pthread_impl.h b/test/Modules/Inputs/crash-recovery/usr/include/pthread/pthread_impl.h
new file mode 100644
index 000000000000..21a720a7c3cd
--- /dev/null
+++ b/test/Modules/Inputs/crash-recovery/usr/include/pthread/pthread_impl.h
@@ -0,0 +1 @@
+#define _PTHREAD_MUTEX_SIG_init 0x32AAABA7
diff --git a/test/Modules/Inputs/crash-recovery/usr/include/pthread_impl.h b/test/Modules/Inputs/crash-recovery/usr/include/pthread_impl.h
new file mode 100644
index 000000000000..21a720a7c3cd
--- /dev/null
+++ b/test/Modules/Inputs/crash-recovery/usr/include/pthread_impl.h
@@ -0,0 +1 @@
+#define _PTHREAD_MUTEX_SIG_init 0x32AAABA7
diff --git a/test/Modules/Inputs/crash-recovery/usr/include/stdio.h b/test/Modules/Inputs/crash-recovery/usr/include/stdio.h
new file mode 100644
index 000000000000..f41e09c35a41
--- /dev/null
+++ b/test/Modules/Inputs/crash-recovery/usr/include/stdio.h
@@ -0,0 +1,3 @@
+typedef struct { int id; } FILE;
+int fprintf(FILE*restrict, const char* restrict format, ...);
+extern FILE *__stderrp;
diff --git a/test/Modules/Inputs/crash-recovery/usr/include/tcl-private/header.h b/test/Modules/Inputs/crash-recovery/usr/include/tcl-private/header.h
new file mode 100644
index 000000000000..0e8fb64a7121
--- /dev/null
+++ b/test/Modules/Inputs/crash-recovery/usr/include/tcl-private/header.h
@@ -0,0 +1,2 @@
+// tcl-private/header.h
+#define TCL_PRIVATE 1
diff --git a/test/Modules/Inputs/cxx-decls-imported.h b/test/Modules/Inputs/cxx-decls-imported.h
index a4910fee753e..0a172150fc14 100644
--- a/test/Modules/Inputs/cxx-decls-imported.h
+++ b/test/Modules/Inputs/cxx-decls-imported.h
@@ -50,3 +50,8 @@ namespace Alias = Aliased;
struct InhCtorA { InhCtorA(int); };
struct InhCtorB : InhCtorA { using InhCtorA::InhCtorA; };
+
+struct ClassWithVBases : HasFriends, virtual HasNontrivialDefaultConstructor {
+ int n;
+};
+struct ClassWithVBases;
diff --git a/test/Modules/Inputs/cxx-templates-common.h b/test/Modules/Inputs/cxx-templates-common.h
index a9ca62448671..8e730c8a852c 100644
--- a/test/Modules/Inputs/cxx-templates-common.h
+++ b/test/Modules/Inputs/cxx-templates-common.h
@@ -53,4 +53,21 @@ template<typename T> struct WithAnonymousDecls {
typedef int X;
};
+namespace hidden_specializations {
+ template<typename T> void fn() {}
+
+ template<typename T> struct cls {
+ static void nested_fn() {}
+ struct nested_cls {};
+ static int nested_var;
+ enum class nested_enum {};
+
+ template<typename U> static void nested_fn_t() {}
+ template<typename U> struct nested_cls_t {};
+ template<typename U> static int nested_var_t;
+ };
+
+ template<typename T> int var;
+}
+
#include "cxx-templates-textual.h"
diff --git a/test/Modules/Inputs/cxx-templates-unimported.h b/test/Modules/Inputs/cxx-templates-unimported.h
new file mode 100644
index 000000000000..c2b6b915924b
--- /dev/null
+++ b/test/Modules/Inputs/cxx-templates-unimported.h
@@ -0,0 +1,43 @@
+#include "cxx-templates-common.h"
+
+namespace hidden_specializations {
+ // explicit specializations
+ template<> void fn<int>() {}
+ template<> struct cls<int> {
+ void nested_fn();
+ struct nested_cls;
+ static int nested_var;
+ enum nested_enum : int;
+ };
+ template<> int var<int>;
+
+ // partial specializations
+ template<typename T> struct cls<T*> {
+ void nested_fn();
+ struct nested_cls;
+ static int nested_var;
+ enum nested_enum : int;
+ };
+ template<typename T> int var<T*>;
+
+ // member specializations
+ template<> void cls<void>::nested_fn() {}
+ template<> struct cls<void>::nested_cls {};
+ template<> int cls<void>::nested_var;
+ template<> enum class cls<void>::nested_enum { e };
+ template<> template<typename U> void cls<void>::nested_fn_t() {}
+ template<> template<typename U> struct cls<void>::nested_cls_t {};
+ template<> template<typename U> int cls<void>::nested_var_t;
+
+ // specializations instantiated here are ok if their pattern is
+ inline void use_stuff() {
+ fn<char>();
+ cls<char>();
+ (void)var<char>;
+ cls<char*>();
+ (void)var<char*>;
+ cls<void>::nested_fn_t<char>();
+ cls<void>::nested_cls_t<char>();
+ (void)cls<void>::nested_var_t<char>;
+ }
+}
diff --git a/test/Modules/Inputs/explicit-build/a.h b/test/Modules/Inputs/explicit-build/a.h
index 5e3602f58ffe..a52f7357ff75 100644
--- a/test/Modules/Inputs/explicit-build/a.h
+++ b/test/Modules/Inputs/explicit-build/a.h
@@ -1,4 +1,4 @@
-#if !__building_module(a)
+#if !__building_module(a) && !BUILDING_A_PCH
#error "should only get here when building module a"
#endif
diff --git a/test/Modules/Inputs/getSourceDescriptor-crash/h1.h b/test/Modules/Inputs/getSourceDescriptor-crash/h1.h
new file mode 100644
index 000000000000..6f70f09beec2
--- /dev/null
+++ b/test/Modules/Inputs/getSourceDescriptor-crash/h1.h
@@ -0,0 +1 @@
+#pragma once
diff --git a/test/Modules/Inputs/getSourceDescriptor-crash/module.modulemap b/test/Modules/Inputs/getSourceDescriptor-crash/module.modulemap
new file mode 100644
index 000000000000..2006ed5fde22
--- /dev/null
+++ b/test/Modules/Inputs/getSourceDescriptor-crash/module.modulemap
@@ -0,0 +1,3 @@
+module foo {
+ header "h1.h"
+}
diff --git a/test/Modules/Inputs/merge-decl-context/a.h b/test/Modules/Inputs/merge-decl-context/a.h
index 89cc7120fd17..7be90b1535de 100644
--- a/test/Modules/Inputs/merge-decl-context/a.h
+++ b/test/Modules/Inputs/merge-decl-context/a.h
@@ -21,4 +21,8 @@ inline A<int> ff(int i) {
return fff<A<int>>(&i);
}
+struct Aggregate {
+ int member;
+};
+
#endif
diff --git a/test/Modules/Inputs/module.map b/test/Modules/Inputs/module.map
index 632517dd363f..6846690c8498 100644
--- a/test/Modules/Inputs/module.map
+++ b/test/Modules/Inputs/module.map
@@ -215,6 +215,8 @@ module cxx_linkage_cache {
module cxx_templates_common {
header "cxx-templates-common.h"
+
+ explicit module unimported { header "cxx-templates-unimported.h" }
}
module cxx_templates_a {
@@ -393,3 +395,26 @@ module ElaboratedTypeStructs {
header "elaborated-type-structs.h"
}
}
+
+// We import a module, then declare a method with selector stringValue in
+// MethodPoolCombined1.h. In MethodPoolCombined2.h, we import another module
+// that also contains a method for selector stringValue. We make sure that
+// the method pool entry for stringValue in this module is complete.
+module MethodPoolCombined {
+ header "MethodPoolCombined1.h"
+ header "MethodPoolCombined2.h"
+}
+
+module MethodPoolString1 {
+ header "MethodPoolString1.h"
+}
+
+module MethodPoolString2 {
+ header "MethodPoolString2.h"
+}
+
+module Empty {}
+
+module MacroFabs1 {
+ header "MacroFabs1.h"
+}
diff --git a/test/Modules/Inputs/non-module.h b/test/Modules/Inputs/non-module.h
new file mode 100644
index 000000000000..c295900bd108
--- /dev/null
+++ b/test/Modules/Inputs/non-module.h
@@ -0,0 +1,4 @@
+#ifndef NON_MODULE_H
+#define NON_MODULE_H
+
+#endif
diff --git a/test/Modules/Inputs/pch-import-module-with-macro.pch b/test/Modules/Inputs/pch-import-module-with-macro.pch
new file mode 100644
index 000000000000..c06d7728b620
--- /dev/null
+++ b/test/Modules/Inputs/pch-import-module-with-macro.pch
@@ -0,0 +1,3 @@
+
+@import MacroFabs1;
+
diff --git a/test/Modules/Inputs/suggest-include/empty.h b/test/Modules/Inputs/suggest-include/empty.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/test/Modules/Inputs/suggest-include/empty.h
diff --git a/test/Modules/Inputs/suggest-include/module.modulemap b/test/Modules/Inputs/suggest-include/module.modulemap
new file mode 100644
index 000000000000..46afd7b2c218
--- /dev/null
+++ b/test/Modules/Inputs/suggest-include/module.modulemap
@@ -0,0 +1,22 @@
+module X {
+ module Empty { header "empty.h" }
+
+ exclude header "textual1.h"
+ textual header "textual2.h"
+ textual header "textual3.h"
+
+ module A { header "usetextual1.h" }
+ module B { header "usetextual2.h" }
+ module C { header "usetextual3.h" }
+ module D { header "usetextual4.h" }
+ module E { header "usetextual5.h" }
+
+ module P { private header "private1.h" }
+ module Q { private header "private2.h" }
+ module R { private header "private3.h" }
+ module S { header "useprivate1.h" export * }
+ module T { header "useprivate3.h" }
+}
+
+module Other { textual header "textual4.h" }
+
diff --git a/test/Modules/Inputs/suggest-include/private1.h b/test/Modules/Inputs/suggest-include/private1.h
new file mode 100644
index 000000000000..afc7ac71bb46
--- /dev/null
+++ b/test/Modules/Inputs/suggest-include/private1.h
@@ -0,0 +1 @@
+extern int private1;
diff --git a/test/Modules/Inputs/suggest-include/private2.h b/test/Modules/Inputs/suggest-include/private2.h
new file mode 100644
index 000000000000..24a1893d31eb
--- /dev/null
+++ b/test/Modules/Inputs/suggest-include/private2.h
@@ -0,0 +1 @@
+extern int private2;
diff --git a/test/Modules/Inputs/suggest-include/private3.h b/test/Modules/Inputs/suggest-include/private3.h
new file mode 100644
index 000000000000..26852af2a6a8
--- /dev/null
+++ b/test/Modules/Inputs/suggest-include/private3.h
@@ -0,0 +1 @@
+extern int private3;
diff --git a/test/Modules/Inputs/suggest-include/textual1.h b/test/Modules/Inputs/suggest-include/textual1.h
new file mode 100644
index 000000000000..5b18bfb36856
--- /dev/null
+++ b/test/Modules/Inputs/suggest-include/textual1.h
@@ -0,0 +1 @@
+#define FOO(X) X
diff --git a/test/Modules/Inputs/suggest-include/textual2.h b/test/Modules/Inputs/suggest-include/textual2.h
new file mode 100644
index 000000000000..0c06d4ea454b
--- /dev/null
+++ b/test/Modules/Inputs/suggest-include/textual2.h
@@ -0,0 +1 @@
+EXPAND_MACRO
diff --git a/test/Modules/Inputs/suggest-include/textual3.h b/test/Modules/Inputs/suggest-include/textual3.h
new file mode 100644
index 000000000000..1e5252116103
--- /dev/null
+++ b/test/Modules/Inputs/suggest-include/textual3.h
@@ -0,0 +1 @@
+extern int textual3;
diff --git a/test/Modules/Inputs/suggest-include/textual4.h b/test/Modules/Inputs/suggest-include/textual4.h
new file mode 100644
index 000000000000..091e0c0ac19d
--- /dev/null
+++ b/test/Modules/Inputs/suggest-include/textual4.h
@@ -0,0 +1 @@
+extern int textual4;
diff --git a/test/Modules/Inputs/suggest-include/textual5.h b/test/Modules/Inputs/suggest-include/textual5.h
new file mode 100644
index 000000000000..d808617d5000
--- /dev/null
+++ b/test/Modules/Inputs/suggest-include/textual5.h
@@ -0,0 +1 @@
+extern int textual5;
diff --git a/test/Modules/Inputs/suggest-include/useprivate1.h b/test/Modules/Inputs/suggest-include/useprivate1.h
new file mode 100644
index 000000000000..817b900ecccf
--- /dev/null
+++ b/test/Modules/Inputs/suggest-include/useprivate1.h
@@ -0,0 +1 @@
+#include "private1.h"
diff --git a/test/Modules/Inputs/suggest-include/useprivate3.h b/test/Modules/Inputs/suggest-include/useprivate3.h
new file mode 100644
index 000000000000..5d5d221b87b8
--- /dev/null
+++ b/test/Modules/Inputs/suggest-include/useprivate3.h
@@ -0,0 +1 @@
+#include "private3.h"
diff --git a/test/Modules/Inputs/suggest-include/usetextual1.h b/test/Modules/Inputs/suggest-include/usetextual1.h
new file mode 100644
index 000000000000..34ab1c76bccd
--- /dev/null
+++ b/test/Modules/Inputs/suggest-include/usetextual1.h
@@ -0,0 +1,2 @@
+#include "textual1.h"
+FOO(extern int usetextual1;)
diff --git a/test/Modules/Inputs/suggest-include/usetextual2.h b/test/Modules/Inputs/suggest-include/usetextual2.h
new file mode 100644
index 000000000000..95b244573636
--- /dev/null
+++ b/test/Modules/Inputs/suggest-include/usetextual2.h
@@ -0,0 +1,2 @@
+#define EXPAND_MACRO extern int usetextual2;
+#include "textual2.h"
diff --git a/test/Modules/Inputs/suggest-include/usetextual3.h b/test/Modules/Inputs/suggest-include/usetextual3.h
new file mode 100644
index 000000000000..15a75cc839f8
--- /dev/null
+++ b/test/Modules/Inputs/suggest-include/usetextual3.h
@@ -0,0 +1 @@
+#include "textual3.h"
diff --git a/test/Modules/Inputs/suggest-include/usetextual4.h b/test/Modules/Inputs/suggest-include/usetextual4.h
new file mode 100644
index 000000000000..395bb6fd65b3
--- /dev/null
+++ b/test/Modules/Inputs/suggest-include/usetextual4.h
@@ -0,0 +1 @@
+#include "textual4.h"
diff --git a/test/Modules/Inputs/suggest-include/usetextual5.h b/test/Modules/Inputs/suggest-include/usetextual5.h
new file mode 100644
index 000000000000..a7335d37aeb8
--- /dev/null
+++ b/test/Modules/Inputs/suggest-include/usetextual5.h
@@ -0,0 +1 @@
+#include "textual5.h"
diff --git a/test/Modules/Inputs/typo.h b/test/Modules/Inputs/typo.h
new file mode 100644
index 000000000000..764c00b7c387
--- /dev/null
+++ b/test/Modules/Inputs/typo.h
@@ -0,0 +1,6 @@
+@import Empty;
+
+@interface NSString
++ (id)alloc;
+@end
+
diff --git a/test/Modules/ModuleDebugInfo.cpp b/test/Modules/ModuleDebugInfo.cpp
index bbe36cb225d0..998d36327ef5 100644
--- a/test/Modules/ModuleDebugInfo.cpp
+++ b/test/Modules/ModuleDebugInfo.cpp
@@ -8,7 +8,6 @@
// RUN: %clang_cc1 -triple %itanium_abi_triple -x objective-c++ -std=c++11 -debug-info-kind=limited -fmodules -fmodule-format=obj -fimplicit-module-maps -DMODULES -fmodules-cache-path=%t %s -I %S/Inputs -I %t -emit-llvm -o %t.ll -mllvm -debug-only=pchcontainer &>%t-mod.ll
// RUN: cat %t-mod.ll | FileCheck %s
// RUN: cat %t-mod.ll | FileCheck --check-prefix=CHECK-NEG %s
-// RUN: cat %t-mod.ll | FileCheck --check-prefix=CHECK-DWO %s
// PCH:
// RUN: %clang_cc1 -triple %itanium_abi_triple -x c++ -std=c++11 -emit-pch -fmodule-format=obj -I %S/Inputs -o %t.pch %S/Inputs/DebugCXX.h -mllvm -debug-only=pchcontainer &>%t-pch.ll
@@ -21,25 +20,66 @@
// CHECK: distinct !DICompileUnit(language: DW_LANG_{{.*}}C_plus_plus,
// CHECK-SAME: isOptimized: false,
-// CHECK-SAME-NOT: splitDebugFilename:
-// CHECK-DWO: dwoId:
+// CHECK-NOT: splitDebugFilename:
+// CHECK-SAME: dwoId:
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "Enum"
// CHECK-SAME: identifier: "_ZTSN8DebugCXX4EnumE")
// CHECK: !DINamespace(name: "DebugCXX"
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type,
+// CHECK-NOT: name:
+// CHECK-SAME: )
+
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type,
+// CHECK-NOT: name:
+// CHECK-SAME: )
+
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type,
+// CHECK-NOT: name:
+// CHECK-SAME: identifier: "_ZTS11TypedefEnum")
+
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type,
+// CHECK-NOT: name:
+// CHECK-SAME: )
+// CHECK: !DIEnumerator(name: "e5", value: 5)
+
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "B",
+// no mangled name here yet.
+
+// This type is anchored by a function parameter.
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A<void>"
+// CHECK-SAME: templateParams:
+// CHECK-SAME: identifier: "_ZTSN8DebugCXX1AIJvEEE")
+
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Struct"
// CHECK-SAME: identifier: "_ZTSN8DebugCXX6StructE")
+// This type is anchored by an explicit template instantiation.
// CHECK: !DICompositeType(tag: DW_TAG_class_type,
// CHECK-SAME: name: "Template<int, DebugCXX::traits<int> >"
+// CHECK-SAME: templateParams:
// CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIiNS_6traitsIiEEEE")
-// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A<void>"
-// CHECK-SAME: identifier: "_ZTSN8DebugCXX1AIJvEEE")
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "traits<int>"
+// CHECK-SAME: flags: DIFlagFwdDecl
+// CHECK-SAME: identifier: "_ZTSN8DebugCXX6traitsIiEE")
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "traits<float>"
+// CHECK-SAME: templateParams:
+// CHECK-SAME: identifier: "_ZTSN8DebugCXX6traitsIfEE")
+
+// CHECK: !DICompositeType(tag: DW_TAG_class_type,
+// CHECK-SAME: name: "Template<long, DebugCXX::traits<long> >"
+// CHECK-SAME: templateParams:
+// CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIlNS_6traitsIlEEEE")
+
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "FloatInstantiation"
+// no mangled name here yet.
// CHECK: !DICompositeType(tag: DW_TAG_class_type,
// CHECK-SAME: name: "Template<float, DebugCXX::traits<float> >"
+// CHECK-SAME: flags: DIFlagFwdDecl
// CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIfNS_6traitsIfEEEE")
// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "FwdVirtual"
@@ -47,10 +87,52 @@
// CHECK-SAME: identifier: "_ZTS10FwdVirtual")
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "_vptr$FwdVirtual"
-// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "FloatInstatiation"
-// no mangled name here yet.
+// CHECK: !DICompositeType(tag: DW_TAG_union_type,
+// CHECK-NOT: name:
+// CHECK-SAME: identifier: "_ZTS12TypedefUnion")
-// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "B",
-// no mangled name here yet.
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK-NOT: name:
+// CHECK-SAME: identifier: "_ZTS13TypedefStruct")
+
+// CHECK: !DICompositeType(tag: DW_TAG_union_type,
+// CHECK-NOT: name:
+// CHECK-SAME: )
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK-NOT: name:
+// CHECK-SAME: )
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK-SAME: name: "InAnonymousNamespace",
+// CHECK-SAME: elements: !{{[0-9]+}})
+
+// CHECK: ![[DERIVED:.*]] = {{.*}}!DICompositeType(tag: DW_TAG_class_type, name: "Derived",
+// CHECK-SAME: identifier: "_ZTS7Derived")
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "B", scope: ![[DERIVED]],
+// CHECK-SAME: elements: ![[B_MBRS:.*]], vtableHolder:
+// CHECK: ![[B_MBRS]] = !{{{.*}}, ![[GET_PARENT:.*]]}
+// CHECK: ![[GET_PARENT]] = !DISubprogram(name: "getParent"
+
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "TypedefTemplate",
+// CHECK-SAME: baseType: ![[BASE:.*]])
+// CHECK: ![[BASE]] = !DICompositeType(tag: DW_TAG_class_type,
+// CHECK-SAME: name: "Template1<void *>",
+// CHECK-SAME: flags: DIFlagFwdDecl,
+// CHECK-SAME: identifier: "_ZTS9Template1IPvE")
+
+// Explicit instatiation.
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "Template1<int>",
+// CHECK-SAME: templateParams:
+// CHECK-SAME: identifier: "_ZTS9Template1IiE")
+
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "FwdDeclTemplate<int>",
+// CHECK-SAME: flags: DIFlagFwdDecl
+// CHECK-SAME: identifier: "_ZTS15FwdDeclTemplateIiE")
+
+// Forward-declared member of a template.
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Member",
+// CHECK-SAME: flags: DIFlagFwdDecl
+// CHECK-SAME: identifier: "_ZTSN21FwdDeclTemplateMemberIiE6MemberE")
// CHECK-NEG-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: "PureForwardDecl"
diff --git a/test/Modules/ModuleDebugInfo.m b/test/Modules/ModuleDebugInfo.m
index 0974f38cc22e..ce35c7c8361f 100644
--- a/test/Modules/ModuleDebugInfo.m
+++ b/test/Modules/ModuleDebugInfo.m
@@ -10,13 +10,14 @@
// RUN: -I %S/Inputs -I %t -emit-llvm -o %t.ll \
// RUN: -mllvm -debug-only=pchcontainer &>%t-mod.ll
// RUN: cat %t-mod.ll | FileCheck %s
-// RUN: cat %t-mod.ll | FileCheck %s --check-prefix=MODULE-CHECK
+// RUN: cat %t-mod.ll | FileCheck %s --check-prefix=CHECK2
// PCH:
// RUN: %clang_cc1 -x objective-c -emit-pch -fmodule-format=obj -I %S/Inputs \
// RUN: -o %t.pch %S/Inputs/DebugObjC.h \
// RUN: -mllvm -debug-only=pchcontainer &>%t-pch.ll
// RUN: cat %t-pch.ll | FileCheck %s
+// RUN: cat %t-pch.ll | FileCheck %s --check-prefix=CHECK2
#ifdef MODULES
@import DebugObjC;
@@ -24,28 +25,69 @@
// CHECK: distinct !DICompileUnit(language: DW_LANG_ObjC
// CHECK-SAME: isOptimized: false,
-// CHECK: !DICompositeType(tag: DW_TAG_structure_type,
-// CHECK-SAME: name: "FwdDecl",
-// CHECK: !DICompositeType(tag: DW_TAG_structure_type,
-// CHECK-SAME: name: "ObjCClass",
-// CHECK: !DIObjCProperty(name: "property",
-// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "ivar"
-// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "InnerEnum"
-// CHECK: !DISubprogram(name: "+[ObjCClass classMethod]"
-// CHECK: !DISubprogram(name: "-[ObjCClass instanceMethodWithInt:]"
-// CHECK: !DISubprogram(name: "-[Category(Category) categoryMethod]"
-// MODULE-CHECK: !DICompositeType(tag: DW_TAG_enumeration_type,
-// MODULE-CHECK-SAME: scope: ![[MODULE:[0-9]+]],
-// MODULE-CHECK: ![[MODULE]] = !DIModule(scope: null, name: "DebugObjC"
-// MODULE-CHECK: !DICompositeType(tag: DW_TAG_structure_type,
-// MODULE-CHECK-SAME: name: "FwdDecl",
-// MODULE-CHECK-SAME: scope: ![[MODULE]],
-// MODULE-CHECK: !DICompositeType(tag: DW_TAG_structure_type,
-// MODULE-CHECK-SAME: name: "ObjCClass",
-// MODULE-CHECK-SAME: scope: ![[MODULE]],
-// MODULE-CHECK: !DISubprogram(name: "+[ObjCClass classMethod]",
-// MODULE-CHECK-SAME: scope: ![[MODULE]],
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type,
+// CHECK-SAME: scope: ![[MODULE:[0-9]+]],
+// CHECK: ![[MODULE]] = !DIModule(scope: null, name: "DebugObjC
+
+// CHECK: ![[TD_ENUM:.*]] = !DICompositeType(tag: DW_TAG_enumeration_type,
+// CHECK-NOT: name:
+// CHECK-SAME: elements:
+
+// CHECK: !DISubprogram(name: "+[ObjCClass classMethod]",
+// CHECK-SAME: scope: ![[MODULE]],
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ObjCClass",
+// CHECK-SAME: scope: ![[MODULE]],
+// CHECK-SAME: elements
// The forward declaration should not be in the module scope.
-// MODULE-CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "OpaqueData", file
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "OpaqueData", file
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "FwdDecl",
+// CHECK-SAME: scope: ![[MODULE]],
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ObjCClassWithPrivateIVars",
+// CHECK-SAME: scope: ![[MODULE]],
+// CHECK-SAME: elements
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "FwdDeclared"
+// CHECK-SAME: elements:
+
+// CHECK: ![[TD_UNION:.*]] = distinct !DICompositeType(tag: DW_TAG_union_type,
+// CHECK-NOT: name:
+// CHECK-SAME: elements:
+
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "TypedefUnion",
+// CHECK-SAME: baseType: ![[TD_UNION]])
+
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "TypedefEnum",
+// CHECK-SAME: baseType: ![[TD_ENUM:.*]])
+
+// CHECK: ![[TD_STRUCT:.*]] = distinct !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK-NOT: name:
+// CHECK-SAME: elements:
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "TypedefStruct",
+// CHECK-SAME: baseType: ![[TD_STRUCT]])
+
+// CHECK: !DICompositeType(tag: DW_TAG_union_type,
+// CHECK-NOT: name:
+// CHECK-SAME: )
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK-NOT: name:
+// CHECK-SAME: )
+
+// CHECK-NEG-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: "PureForwardDecl"
+
+// The output order is sublty different for module vs. pch,
+// so these are checked separately:
+//
+// CHECK2: !DISubprogram(name: "+[ObjCClass classMethod]"
+// CHECK2: !DISubprogram(name: "-[ObjCClass instanceMethodWithInt:]"
+// CHECK2: !DICompositeType(tag: DW_TAG_structure_type, name: "ObjCClass",
+// CHECK2: !DIObjCProperty(name: "property",
+// CHECK2: !DIDerivedType(tag: DW_TAG_member, name: "ivar"
+// CHECK2: !DISubprogram(name: "-[Category(Category) categoryMethod]"
+// CHECK2: !DICompositeType(tag: DW_TAG_structure_type, name: "FwdDecl",
+// CHECK2: !DIDerivedType(tag: DW_TAG_typedef, name: "InnerEnum"
diff --git a/test/Modules/builtins.m b/test/Modules/builtins.m
index 33d23979ce79..2480e6379cc8 100644
--- a/test/Modules/builtins.m
+++ b/test/Modules/builtins.m
@@ -1,10 +1,26 @@
-@import builtin;
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs %s -verify
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs -x c %s -verify
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs -x objective-c++ %s -verify
+
+// RUN: rm -rf %t.pch.cache
+// RUN: %clang_cc1 -fmodules-cache-path=%t.pch.cache -fmodules -fimplicit-module-maps -I %S/Inputs -emit-pch -o %t.pch -x objective-c-header %S/Inputs/use-builtin.h
+// RUN: %clang_cc1 -fmodules-cache-path=%t.pch.cache -fmodules -fimplicit-module-maps -I %S/Inputs %s -include-pch %t.pch %s -verify
+
+// expected-no-diagnostics
+
+void use_constant_string_builtins1(void) {
+ (void)__builtin___CFStringMakeConstantString("");
+ (void)__builtin___NSStringMakeConstantString("");
+}
+
+#include "builtin.h"
int foo() {
return __builtin_object_size(p, 0);
}
-@import builtin.sub;
+#include "builtin_sub.h"
int bar() {
return __builtin_object_size(p, 0);
@@ -14,11 +30,7 @@ int baz() {
return IS_CONST(0);
}
-// RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs %s -verify
-
-// RUN: rm -rf %t.pch.cache
-// RUN: %clang_cc1 -fmodules-cache-path=%t.pch.cache -fmodules -fimplicit-module-maps -I %S/Inputs -emit-pch -o %t.pch -x objective-c-header %S/Inputs/use-builtin.h
-// RUN: %clang_cc1 -fmodules-cache-path=%t.pch.cache -fmodules -fimplicit-module-maps -I %S/Inputs %s -include-pch %t.pch %s -verify
-
-// expected-no-diagnostics
+void use_constant_string_builtins2(void) {
+ (void)__builtin___CFStringMakeConstantString("");
+ (void)__builtin___NSStringMakeConstantString("");
+}
diff --git a/test/Modules/crash-vfs-path-emptydir-entries.m b/test/Modules/crash-vfs-path-emptydir-entries.m
new file mode 100644
index 000000000000..01560984ff71
--- /dev/null
+++ b/test/Modules/crash-vfs-path-emptydir-entries.m
@@ -0,0 +1,49 @@
+// REQUIRES: crash-recovery, shell
+
+// FIXME: This XFAIL is cargo-culted from crash-report.c. Do we need it?
+// XFAIL: mingw32
+
+// Test clang can collect symbolic link headers used in modules.
+// crash reproducer if there's a symbolic link header file used in a module.
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/i %t/m %t %t/sysroot
+// RUN: cp -a %S/Inputs/crash-recovery/usr %t/i/
+
+// RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \
+// RUN: %clang -fsyntax-only %s -I %/t/i -isysroot %/t/sysroot/ \
+// RUN: -fmodules -fmodules-cache-path=%t/m/ 2>&1 | FileCheck %s
+
+// RUN: FileCheck --check-prefix=CHECKSRC %s -input-file %t/crash-vfs-*.m
+// RUN: FileCheck --check-prefix=CHECKSH %s -input-file %t/crash-vfs-*.sh
+// RUN: FileCheck --check-prefix=CHECKYAML %s -input-file \
+// RUN: %t/crash-vfs-*.cache/vfs/vfs.yaml
+// RUN: find %t/crash-vfs-*.cache/vfs | \
+// RUN: grep "usr/include/stdio.h" | count 1
+
+#include "usr/include/stdio.h"
+
+// CHECK: Preprocessed source(s) and associated run script(s) are located at:
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.m
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
+
+// CHECKSRC: @import cstd.stdio;
+
+// CHECKSH: # Crash reproducer
+// CHECKSH-NEXT: # Driver args: "-fsyntax-only"
+// CHECKSH-NEXT: # Original command: {{.*$}}
+// CHECKSH-NEXT: "-cc1"
+// CHECKSH: "-isysroot" "{{[^"]*}}/sysroot/"
+// CHECKSH-NOT: "-fmodules-cache-path="
+// CHECKSH: "crash-vfs-{{[^ ]*}}.m"
+// CHECKSH: "-ivfsoverlay" "crash-vfs-{{[^ ]*}}.cache/vfs/vfs.yaml"
+// CHECKSH: "-fmodules-cache-path=crash-vfs-{{[^ ]*}}.cache/modules"
+
+// CHECKYAML: 'type': 'directory',
+// CHECKYAML: 'name': "",
+// CHECKYAML-NEXT: 'contents': [
+// CHECKYAML-NEXT: {
+// CHECKYAML-NEXT: 'type': 'file',
+// CHECKYAML-NEXT: 'name': "pthread_impl.h",
+// CHECKYAML-NEXT: 'external-contents': "/{{.*}}/i/usr/include/pthread_impl.h"
+// CHECKYAML-NEXT: },
diff --git a/test/Modules/crash-vfs-path-symlink-component.m b/test/Modules/crash-vfs-path-symlink-component.m
new file mode 100644
index 000000000000..6a41188b271a
--- /dev/null
+++ b/test/Modules/crash-vfs-path-symlink-component.m
@@ -0,0 +1,68 @@
+// REQUIRES: crash-recovery, shell
+
+// FIXME: This XFAIL is cargo-culted from crash-report.c. Do we need it?
+// XFAIL: mingw32
+
+// Test that clang is capable of collecting the right header files in the
+// crash reproducer if there's a symbolic link component in the path.
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/i %t/m %t %t/sysroot
+// RUN: cp -a %S/Inputs/crash-recovery/usr %t/i/
+// RUN: ln -s include/tcl-private %t/i/usr/x
+
+// RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \
+// RUN: %clang -fsyntax-only %s -I %/t/i -isysroot %/t/sysroot/ \
+// RUN: -fmodules -fmodules-cache-path=%t/m/ 2>&1 | FileCheck %s
+
+// RUN: FileCheck --check-prefix=CHECKSRC %s -input-file %t/crash-vfs-*.m
+// RUN: FileCheck --check-prefix=CHECKSH %s -input-file %t/crash-vfs-*.sh
+// RUN: FileCheck --check-prefix=CHECKYAML %s -input-file \
+// RUN: %t/crash-vfs-*.cache/vfs/vfs.yaml
+// RUN: find %t/crash-vfs-*.cache/vfs | \
+// RUN: grep "usr/include/stdio.h" | count 1
+
+#include "usr/x/../stdio.h"
+
+// CHECK: Preprocessed source(s) and associated run script(s) are located at:
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.m
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
+
+// CHECKSRC: @import cstd.stdio;
+
+// CHECKSH: # Crash reproducer
+// CHECKSH-NEXT: # Driver args: "-fsyntax-only"
+// CHECKSH-NEXT: # Original command: {{.*$}}
+// CHECKSH-NEXT: "-cc1"
+// CHECKSH: "-isysroot" "{{[^"]*}}/sysroot/"
+// CHECKSH-NOT: "-fmodules-cache-path="
+// CHECKSH: "crash-vfs-{{[^ ]*}}.m"
+// CHECKSH: "-ivfsoverlay" "crash-vfs-{{[^ ]*}}.cache/vfs/vfs.yaml"
+// CHECKSH: "-fmodules-cache-path=crash-vfs-{{[^ ]*}}.cache/modules"
+
+// CHECKYAML: 'case-sensitive':
+// CHECKYAML-NEXT: 'use-external-names': 'false',
+// CHECKYAML-NEXT: 'overlay-relative': 'true',
+
+// CHECKYAML: 'type': 'directory'
+// CHECKYAML: 'name': "/[[PATH:.*]]/i/usr",
+// CHECKYAML-NEXT: 'contents': [
+// CHECKYAML-NEXT: {
+// CHECKYAML-NEXT: 'type': 'file',
+// CHECKYAML-NEXT: 'name': "module.map",
+// CHECKYAML-NEXT: 'external-contents': "/[[PATH]]/i/usr/include/module.map"
+// CHECKYAML-NEXT: },
+
+// Test that by using the previous generated YAML file clang is able to find the
+// right files inside the overlay and map the virtual request for a path that
+// previously contained a symlink to work. To make sure of this, wipe out the
+// %/t/i directory containing the symlink component.
+
+// RUN: rm -rf %/t/i
+// RUN: unset FORCE_CLANG_DIAGNOSTICS_CRASH
+// RUN: %clang -E %s -I %/t/i -isysroot %/t/sysroot/ \
+// RUN: -ivfsoverlay %t/crash-vfs-*.cache/vfs/vfs.yaml -fmodules \
+// RUN: -fmodules-cache-path=%t/m/ 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECKOVERLAY
+
+// CHECKOVERLAY: @import cstd.stdio; /* clang -E: implicit import for "/{{[^ ].*}}/i/usr/x/../stdio.h" */
diff --git a/test/Modules/crash-vfs-path-symlink-topheader.m b/test/Modules/crash-vfs-path-symlink-topheader.m
new file mode 100644
index 000000000000..72b666a8127c
--- /dev/null
+++ b/test/Modules/crash-vfs-path-symlink-topheader.m
@@ -0,0 +1,51 @@
+// REQUIRES: crash-recovery, shell
+
+// FIXME: This XFAIL is cargo-culted from crash-report.c. Do we need it?
+// XFAIL: mingw32
+
+// Test clang can collect symbolic link headers used in modules.
+// crash reproducer if there's a symbolic link header file used in a module.
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/i %t/m %t %t/sysroot
+// RUN: cp -a %S/Inputs/crash-recovery/usr %t/i/
+// RUN: rm -f %t/i/usr/include/pthread_impl.h
+// RUN: ln -s pthread/pthread_impl.h %t/i/usr/include/pthread_impl.h
+
+// RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \
+// RUN: %clang -fsyntax-only %s -I %/t/i -isysroot %/t/sysroot/ \
+// RUN: -fmodules -fmodules-cache-path=%t/m/ 2>&1 | FileCheck %s
+
+// RUN: FileCheck --check-prefix=CHECKSRC %s -input-file %t/crash-vfs-*.m
+// RUN: FileCheck --check-prefix=CHECKSH %s -input-file %t/crash-vfs-*.sh
+// RUN: FileCheck --check-prefix=CHECKYAML %s -input-file \
+// RUN: %t/crash-vfs-*.cache/vfs/vfs.yaml
+// RUN: find %t/crash-vfs-*.cache/vfs | \
+// RUN: grep "usr/include/pthread_impl.h" | count 1
+
+#include "usr/include/stdio.h"
+
+// CHECK: Preprocessed source(s) and associated run script(s) are located at:
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.m
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
+
+// CHECKSRC: @import cstd.stdio;
+
+// CHECKSH: # Crash reproducer
+// CHECKSH-NEXT: # Driver args: "-fsyntax-only"
+// CHECKSH-NEXT: # Original command: {{.*$}}
+// CHECKSH-NEXT: "-cc1"
+// CHECKSH: "-isysroot" "{{[^"]*}}/sysroot/"
+// CHECKSH-NOT: "-fmodules-cache-path="
+// CHECKSH: "crash-vfs-{{[^ ]*}}.m"
+// CHECKSH: "-ivfsoverlay" "crash-vfs-{{[^ ]*}}.cache/vfs/vfs.yaml"
+// CHECKSH: "-fmodules-cache-path=crash-vfs-{{[^ ]*}}.cache/modules"
+
+// CHECKYAML: 'type': 'directory',
+// CHECKYAML: 'name': "",
+// CHECKYAML-NEXT: 'contents': [
+// CHECKYAML-NEXT: {
+// CHECKYAML-NEXT: 'type': 'file',
+// CHECKYAML-NEXT: 'name': "pthread_impl.h",
+// CHECKYAML-NEXT: 'external-contents': "/{{.*}}/i/usr/include/pthread_impl.h"
+// CHECKYAML-NEXT: },
diff --git a/test/Modules/crash-vfs-path-traversal.m b/test/Modules/crash-vfs-path-traversal.m
new file mode 100644
index 000000000000..3377de47d0b2
--- /dev/null
+++ b/test/Modules/crash-vfs-path-traversal.m
@@ -0,0 +1,65 @@
+// REQUIRES: crash-recovery, shell, non-ms-sdk, non-ps4-sdk
+
+// FIXME: Canonicalizing paths to remove relative traversal components
+// currenty fails a unittest on windows and is disable by default.
+// FIXME: This XFAIL is cargo-culted from crash-report.c. Do we need it?
+// XFAIL: mingw32
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/i %t/m %t
+
+// RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \
+// RUN: %clang -fsyntax-only %s -I %S/Inputs/crash-recovery -isysroot %/t/i/ \
+// RUN: -fmodules -fmodules-cache-path=%t/m/ 2>&1 | FileCheck %s
+
+// RUN: FileCheck --check-prefix=CHECKSRC %s -input-file %t/crash-vfs-*.m
+// RUN: FileCheck --check-prefix=CHECKSH %s -input-file %t/crash-vfs-*.sh
+// RUN: FileCheck --check-prefix=CHECKYAML %s -input-file \
+// RUN: %t/crash-vfs-*.cache/vfs/vfs.yaml
+// RUN: find %t/crash-vfs-*.cache/vfs | \
+// RUN: grep "Inputs/crash-recovery/usr/include/stdio.h" | count 1
+
+#include "usr/././//////include/../include/./././../include/stdio.h"
+
+// CHECK: Preprocessed source(s) and associated run script(s) are located at:
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.m
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
+
+// CHECKSRC: @import cstd.stdio;
+
+// CHECKSH: # Crash reproducer
+// CHECKSH-NEXT: # Driver args: "-fsyntax-only"
+// CHECKSH-NEXT: # Original command: {{.*$}}
+// CHECKSH-NEXT: "-cc1"
+// CHECKSH: "-isysroot" "{{[^"]*}}/i/"
+// CHECKSH-NOT: "-fmodules-cache-path="
+// CHECKSH: "crash-vfs-{{[^ ]*}}.m"
+// CHECKSH: "-ivfsoverlay" "crash-vfs-{{[^ ]*}}.cache/vfs/vfs.yaml"
+// CHECKSH: "-fmodules-cache-path=crash-vfs-{{[^ ]*}}.cache/modules"
+
+// CHECKYAML: 'case-sensitive':
+// CHECKYAML-NEXT: 'use-external-names': 'false',
+// CHECKYAML-NEXT: 'overlay-relative': 'true',
+// CHECKYAML: 'type': 'directory'
+// CHECKYAML: 'name': "/[[PATH:.*]]/Inputs/crash-recovery/usr/include",
+// CHECKYAML-NEXT: 'contents': [
+// CHECKYAML-NEXT: {
+// CHECKYAML-NEXT: 'type': 'file',
+// CHECKYAML-NEXT: 'name': "module.map",
+// CHECKYAML-NEXT: 'external-contents': "/[[PATH]]/Inputs/crash-recovery/usr/include/module.map"
+// CHECKYAML-NEXT: },
+
+// Replace the paths in the YAML files with relative ".." traversals
+// and fed into clang to test whether we're correctly representing them
+// in the VFS overlay.
+
+// RUN: sed -e "s@usr/include@usr/include/../include@g" \
+// RUN: %t/crash-vfs-*.cache/vfs/vfs.yaml > %t/vfs.yaml
+// RUN: cp %t/vfs.yaml %t/crash-vfs-*.cache/vfs/vfs.yaml
+// RUN: unset FORCE_CLANG_DIAGNOSTICS_CRASH
+// RUN: %clang -E %s -I %S/Inputs/crash-recovery -isysroot %/t/i/ \
+// RUN: -ivfsoverlay %t/crash-vfs-*.cache/vfs/vfs.yaml -fmodules \
+// RUN: -fmodules-cache-path=%t/m/ 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECKOVERLAY
+
+// CHECKOVERLAY: @import cstd.stdio; /* clang -E: implicit import for "/{{[^ ].*}}/usr/././//////include/../include/./././../include/stdio.h" */
diff --git a/test/Modules/crash-vfs-relative-overlay.m b/test/Modules/crash-vfs-relative-overlay.m
new file mode 100644
index 000000000000..870987c58abd
--- /dev/null
+++ b/test/Modules/crash-vfs-relative-overlay.m
@@ -0,0 +1,61 @@
+// REQUIRES: crash-recovery, shell
+
+// FIXME: This XFAIL is cargo-culted from crash-report.c. Do we need it?
+// XFAIL: mingw32
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/i %t/m %t
+
+// RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \
+// RUN: %clang -fsyntax-only -nostdinc %s \
+// RUN: -I %S/Inputs/crash-recovery/usr/include -isysroot %/t/i/ \
+// RUN: -fmodules -fmodules-cache-path=%t/m/ 2>&1 | FileCheck %s
+
+// RUN: FileCheck --check-prefix=CHECKSRC %s -input-file %t/crash-vfs-*.m
+// RUN: FileCheck --check-prefix=CHECKSH %s -input-file %t/crash-vfs-*.sh
+// RUN: FileCheck --check-prefix=CHECKYAML %s -input-file \
+// RUN: %t/crash-vfs-*.cache/vfs/vfs.yaml
+// RUN: find %t/crash-vfs-*.cache/vfs | \
+// RUN: grep "Inputs/crash-recovery/usr/include/stdio.h" | count 1
+
+#include <stdio.h>
+
+// CHECK: Preprocessed source(s) and associated run script(s) are located at:
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.m
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
+
+// CHECKSRC: @import cstd.stdio;
+
+// CHECKSH: # Crash reproducer
+// CHECKSH-NEXT: # Driver args: "-fsyntax-only"
+// CHECKSH-NEXT: # Original command: {{.*$}}
+// CHECKSH-NEXT: "-cc1"
+// CHECKSH: "-resource-dir"
+// CHECKSH: "-isysroot" "{{[^"]*}}/i/"
+// CHECKSH: "crash-vfs-{{[^ ]*}}.m"
+// CHECKSH: "-ivfsoverlay" "crash-vfs-{{[^ ]*}}.cache/vfs/vfs.yaml"
+// CHECKSH: "-fmodules-cache-path=crash-vfs-{{[^ ]*}}.cache/modules"
+
+// CHECKYAML: 'case-sensitive':
+// CHECKYAML-NEXT: 'use-external-names': 'false',
+// CHECKYAML-NEXT: 'overlay-relative': 'true',
+// CHECKYAML: 'type': 'directory'
+// CHECKYAML: 'name': "/[[PATH:.*]]/Inputs/crash-recovery/usr/include",
+// CHECKYAML-NEXT: 'contents': [
+// CHECKYAML-NEXT: {
+// CHECKYAML-NEXT: 'type': 'file',
+// CHECKYAML-NEXT: 'name': "module.map",
+// CHECKYAML-NOT: 'external-contents': "{{[^ ]*}}.cache
+// CHECKYAML-NEXT: 'external-contents': "/[[PATH]]/Inputs/crash-recovery/usr/include/module.map"
+// CHECKYAML-NEXT: },
+
+// Test that reading the YAML file will yield the correct path after
+// the overlay dir is prefixed to access headers in .cache/vfs directory.
+
+// RUN: unset FORCE_CLANG_DIAGNOSTICS_CRASH
+// RUN: %clang -E %s -I %S/Inputs/crash-recovery/usr/include -isysroot %/t/i/ \
+// RUN: -ivfsoverlay %t/crash-vfs-*.cache/vfs/vfs.yaml -fmodules \
+// RUN: -fmodules-cache-path=%t/m/ 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECKOVERLAY
+
+// CHECKOVERLAY: @import cstd.stdio; /* clang -E: implicit import for "/{{[^ ].*}}/usr/include/stdio.h" */
diff --git a/test/Modules/crash-vfs-run-reproducer.m b/test/Modules/crash-vfs-run-reproducer.m
new file mode 100644
index 000000000000..d0eaa931c976
--- /dev/null
+++ b/test/Modules/crash-vfs-run-reproducer.m
@@ -0,0 +1,57 @@
+// REQUIRES: crash-recovery, shell, system-darwin
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/i %t/m %t
+
+// RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \
+// RUN: %clang -fsyntax-only -nostdinc %s \
+// RUN: -I %S/Inputs/crash-recovery/usr/include -isysroot %/t/i/ \
+// RUN: -fmodules -fmodules-cache-path=%t/m/ 2>&1 | FileCheck %s
+
+// RUN: FileCheck --check-prefix=CHECKSRC %s -input-file %t/crash-vfs-*.m
+// RUN: FileCheck --check-prefix=CHECKSH %s -input-file %t/crash-vfs-*.sh
+// RUN: FileCheck --check-prefix=CHECKYAML %s -input-file \
+// RUN: %t/crash-vfs-*.cache/vfs/vfs.yaml
+// RUN: find %t/crash-vfs-*.cache/vfs | \
+// RUN: grep "Inputs/crash-recovery/usr/include/stdio.h" | count 1
+
+#include <stdio.h>
+
+// CHECK: Preprocessed source(s) and associated run script(s) are located at:
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.m
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
+
+// CHECKSRC: @import cstd.stdio;
+
+// CHECKSH: # Crash reproducer
+// CHECKSH-NEXT: # Driver args: "-fsyntax-only"
+// CHECKSH-NEXT: # Original command: {{.*$}}
+// CHECKSH-NEXT: "-cc1"
+// CHECKSH: "-resource-dir"
+// CHECKSH: "-isysroot" "{{[^"]*}}/i/"
+// CHECKSH: "crash-vfs-{{[^ ]*}}.m"
+// CHECKSH: "-ivfsoverlay" "crash-vfs-{{[^ ]*}}.cache/vfs/vfs.yaml"
+// CHECKSH: "-fmodules-cache-path=crash-vfs-{{[^ ]*}}.cache/modules"
+
+// CHECKYAML: 'case-sensitive':
+// CHECKYAML-NEXT: 'use-external-names': 'false',
+// CHECKYAML-NEXT: 'overlay-relative': 'true',
+// CHECKYAML: 'type': 'directory'
+// CHECKYAML: 'name': "/[[PATH:.*]]/Inputs/crash-recovery/usr/include",
+// CHECKYAML-NEXT: 'contents': [
+// CHECKYAML-NEXT: {
+// CHECKYAML-NEXT: 'type': 'file',
+// CHECKYAML-NEXT: 'name': "module.map",
+// CHECKYAML-NOT: 'external-contents': "{{[^ ]*}}.cache
+// CHECKYAML-NEXT: 'external-contents': "/[[PATH]]/Inputs/crash-recovery/usr/include/module.map"
+// CHECKYAML-NEXT: },
+
+// Run the reproducer script - regular exit code is enough to test it works.
+// Note that we don't yet support reusing the modules pcm; what we do
+// support is re-building the modules relying solely on the header files dumped
+// inside .cache/vfs, mapped by .cache/vfs/vfs.yaml.
+
+// RUN: cd %t
+// RUN: rm -rf crash-vfs-run-reproducer-*.cache/modules/*
+// RUN: chmod 755 crash-vfs-*.sh
+// RUN: ./crash-vfs-*.sh
diff --git a/test/Modules/crash-vfs-umbrella-frameworks.m b/test/Modules/crash-vfs-umbrella-frameworks.m
new file mode 100644
index 000000000000..0c3981ddaa88
--- /dev/null
+++ b/test/Modules/crash-vfs-umbrella-frameworks.m
@@ -0,0 +1,55 @@
+// REQUIRES: crash-recovery, shell
+
+// FIXME: This XFAIL is cargo-culted from crash-report.c. Do we need it?
+// XFAIL: mingw32
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/i %t/m %t
+// RUN: cp -a %S/Inputs/crash-recovery/Frameworks %t/i/
+// RUN: mkdir -p %t/i/Frameworks/A.framework/Frameworks
+// RUN: ln -s ../../B.framework %t/i/Frameworks/A.framework/Frameworks/B.framework
+
+// RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \
+// RUN: %clang -nostdinc -fsyntax-only %s \
+// RUN: -F %/t/i/Frameworks -fmodules \
+// RUN: -fmodules-cache-path=%t/m/ 2>&1 | FileCheck %s
+
+// RUN: FileCheck --check-prefix=CHECKYAML %s -input-file \
+// RUN: %t/crash-vfs-*.cache/vfs/vfs.yaml
+// RUN: find %t/crash-vfs-*.cache/vfs | \
+// RUN: grep "B.framework/Headers/B.h" | count 1
+
+// CHECK: Preprocessed source(s) and associated run script(s) are located at:
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.m
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
+
+// CHECKYAML: 'type': 'directory',
+// CHECKYAML: 'name': "/[[PATH:.*]]/i/Frameworks/A.framework/Frameworks/B.framework/Headers",
+// CHECKYAML-NEXT: 'contents': [
+// CHECKYAML-NEXT: {
+// CHECKYAML-NEXT: 'type': 'file',
+// CHECKYAML-NEXT: 'name': "B.h",
+// CHECKYAML-NEXT: 'external-contents': "/[[PATH]]/i/Frameworks/B.framework/Headers/B.h"
+
+// CHECKYAML: 'type': 'directory',
+// CHECKYAML: 'name': "/[[PATH]]/i/Frameworks/B.framework/Headers",
+// CHECKYAML-NEXT: 'contents': [
+// CHECKYAML-NEXT: {
+// CHECKYAML-NEXT: 'type': 'file',
+// CHECKYAML-NEXT: 'name': "B.h",
+// CHECKYAML-NEXT: 'external-contents': "/[[PATH]]/i/Frameworks/B.framework/Headers/B.h"
+
+@import I;
+
+// Run the reproducer script - regular exit code is enough to test it works. The
+// intent here is to guarantee that the collect umbrella headers into the VFS
+// can be used, testing that vfs::recursive_directory_iterator is used correctly
+// Make sure to erase the include paths used to build the modules to guarantee
+// that the VFS overlay won't fallback to use it. Also wipe out the module cache
+// to force header search.
+//
+// RUN: cd %t
+// RUN: rm -rf i
+// RUN: rm -rf crash-vfs-umbrella-*.cache/modules/*
+// RUN: chmod 755 crash-vfs-*.sh
+// RUN: ./crash-vfs-*.sh
diff --git a/test/Modules/cxx-templates.cpp b/test/Modules/cxx-templates.cpp
index ef4e4e420d04..12dfdd0546eb 100644
--- a/test/Modules/cxx-templates.cpp
+++ b/test/Modules/cxx-templates.cpp
@@ -1,9 +1,9 @@
// RUN: rm -rf %t
-// RUN: not %clang_cc1 -x objective-c++ -fmodules -fimplicit-module-maps -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -std=c++11 -ast-dump-lookups | FileCheck %s --check-prefix=CHECK-GLOBAL
-// RUN: not %clang_cc1 -x objective-c++ -fmodules -fimplicit-module-maps -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -std=c++11 -ast-dump-lookups -ast-dump-filter N | FileCheck %s --check-prefix=CHECK-NAMESPACE-N
-// RUN: not %clang_cc1 -x objective-c++ -fmodules -fimplicit-module-maps -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -std=c++11 -ast-dump -ast-dump-filter SomeTemplate | FileCheck %s --check-prefix=CHECK-DUMP
-// RUN: %clang_cc1 -x objective-c++ -fmodules -fimplicit-module-maps -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11
-// RUN: %clang_cc1 -x objective-c++ -fmodules -fimplicit-module-maps -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11 -DEARLY_IMPORT
+// RUN: not %clang_cc1 -x objective-c++ -fmodules -fimplicit-module-maps -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -std=c++14 -ast-dump-lookups 2>/dev/null | FileCheck %s --check-prefix=CHECK-GLOBAL
+// RUN: not %clang_cc1 -x objective-c++ -fmodules -fimplicit-module-maps -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -std=c++14 -ast-dump-lookups -ast-dump-filter N 2>/dev/null | FileCheck %s --check-prefix=CHECK-NAMESPACE-N
+// RUN: not %clang_cc1 -x objective-c++ -fmodules -fimplicit-module-maps -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -std=c++14 -ast-dump -ast-dump-filter SomeTemplate 2>/dev/null | FileCheck %s --check-prefix=CHECK-DUMP
+// RUN: %clang_cc1 -x objective-c++ -fmodules -fimplicit-module-maps -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++14
+// RUN: %clang_cc1 -x objective-c++ -fmodules -fimplicit-module-maps -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++14 -DEARLY_IMPORT
#ifdef EARLY_IMPORT
#include "cxx-templates-textual.h"
@@ -105,7 +105,8 @@ void g() {
TemplateInstantiationVisibility<char[1]> tiv1;
TemplateInstantiationVisibility<char[2]> tiv2;
- TemplateInstantiationVisibility<char[3]> tiv3; // expected-error 2{{must be imported from module 'cxx_templates_b_impl'}}
+ TemplateInstantiationVisibility<char[3]> tiv3; // expected-error 5{{must be imported from module 'cxx_templates_b_impl'}}
+ // expected-note@cxx-templates-b-impl.h:10 3{{explicit specialization declared here}}
// expected-note@cxx-templates-b-impl.h:10 2{{previous definition is here}}
TemplateInstantiationVisibility<char[4]> tiv4;
@@ -172,6 +173,63 @@ bool testFriendInClassTemplate(Std::WithFriend<int> wfi) {
return wfi != wfi;
}
+namespace hidden_specializations {
+ // expected-note@cxx-templates-unimported.h:* 1+{{here}}
+ void test() {
+ // For functions, uses that would trigger instantiations of definitions are
+ // not allowed.
+ fn<void>(); // ok
+ fn<char>(); // ok
+ fn<int>(); // expected-error 1+{{explicit specialization of 'fn<int>' must be imported}}
+ cls<void>::nested_fn(); // expected-error 1+{{explicit specialization of 'nested_fn' must be imported}}
+ cls<void>::nested_fn_t<int>(); // expected-error 1+{{explicit specialization of 'nested_fn_t' must be imported}}
+ cls<void>::nested_fn_t<char>(); // expected-error 1+{{explicit specialization of 'nested_fn_t' must be imported}}
+
+ // For classes, uses that would trigger instantiations of definitions are
+ // not allowed.
+ cls<void> *k0; // ok
+ cls<char> *k1; // ok
+ cls<int> *k2; // ok
+ cls<int*> *k3; // ok
+ cls<void>::nested_cls *nk1; // ok
+ cls<void>::nested_cls_t<int> *nk2; // ok
+ cls<void>::nested_cls_t<char> *nk3; // ok
+ cls<int> uk1; // expected-error 1+{{explicit specialization of 'cls<int>' must be imported}} expected-error 1+{{definition of}}
+ cls<int*> uk3; // expected-error 1+{{partial specialization of 'cls<type-parameter-0-0 *>' must be imported}} expected-error 1+{{definition of}}
+ cls<char*> uk4; // expected-error 1+{{partial specialization of 'cls<type-parameter-0-0 *>' must be imported}} expected-error 1+{{definition of}}
+ cls<void>::nested_cls unk1; // expected-error 1+{{explicit specialization of 'nested_cls' must be imported}} expected-error 1+{{definition of}}
+ cls<void>::nested_cls_t<int> unk2; // expected-error 1+{{explicit specialization of 'nested_cls_t' must be imported}} expected-error 1+{{definition of}}
+ cls<void>::nested_cls_t<char> unk3; // expected-error 1+{{explicit specialization of 'nested_cls_t' must be imported}}
+
+ // For enums, uses that would trigger instantiations of definitions are not
+ // allowed.
+ cls<void>::nested_enum e; // ok
+ (void)cls<void>::nested_enum::e; // expected-error 1+{{definition of 'nested_enum' must be imported}} expected-error 1+{{declaration of 'e'}}
+
+ // For variable template specializations, no uses are allowed because
+ // specializations can change the type.
+ (void)sizeof(var<void>); // ok
+ (void)sizeof(var<char>); // ok
+ (void)sizeof(var<int>); // expected-error 1+{{explicit specialization of 'var<int>' must be imported}}
+ (void)sizeof(var<int*>); // expected-error 1+{{partial specialization of 'var<type-parameter-0-0 *>' must be imported}}
+ (void)sizeof(var<char*>); // expected-error 1+{{partial specialization of 'var<type-parameter-0-0 *>' must be imported}}
+ (void)sizeof(cls<void>::nested_var); // ok
+ (void)cls<void>::nested_var; // expected-error 1+{{explicit specialization of 'nested_var' must be imported}}
+ (void)sizeof(cls<void>::nested_var_t<int>); // expected-error 1+{{explicit specialization of 'nested_var_t' must be imported}}
+ (void)sizeof(cls<void>::nested_var_t<char>); // expected-error 1+{{explicit specialization of 'nested_var_t' must be imported}}
+ }
+
+ void cls<int>::nested_fn() {} // expected-error 1+{{explicit specialization of 'cls<int>' must be imported}} expected-error 1+{{definition of}}
+ struct cls<int>::nested_cls {}; // expected-error 1+{{explicit specialization of 'cls<int>' must be imported}} expected-error 1+{{definition of}}
+ int cls<int>::nested_var; // expected-error 1+{{explicit specialization of 'cls<int>' must be imported}} expected-error 1+{{definition of}}
+ enum cls<int>::nested_enum : int {}; // expected-error 1+{{explicit specialization of 'cls<int>' must be imported}} expected-error 1+{{definition of}}
+
+ template<typename T> void cls<T*>::nested_fn() {} // expected-error 1+{{partial specialization of 'cls<type-parameter-0-0 *>' must be imported}}
+ template<typename T> struct cls<T*>::nested_cls {}; // expected-error 1+{{partial specialization of 'cls<type-parameter-0-0 *>' must be imported}}
+ template<typename T> int cls<T*>::nested_var; // expected-error 1+{{partial specialization of 'cls<type-parameter-0-0 *>' must be imported}}
+ template<typename T> enum cls<T*>::nested_enum : int {}; // expected-error 1+{{partial specialization of 'cls<type-parameter-0-0 *>' must be imported}}
+}
+
namespace Std {
void g(); // expected-error {{functions that differ only in their return type cannot be overloaded}}
// expected-note@cxx-templates-common.h:21 {{previous}}
diff --git a/test/Modules/debug-info-moduleimport.m b/test/Modules/debug-info-moduleimport.m
index bb0ea3149efb..bf60690be40b 100644
--- a/test/Modules/debug-info-moduleimport.m
+++ b/test/Modules/debug-info-moduleimport.m
@@ -1,10 +1,16 @@
// RUN: rm -rf %t
-// RUN: %clang_cc1 -debug-info-kind=limited -fmodules -DGREETING="Hello World" -UNDEBUG -fimplicit-module-maps -fmodules-cache-path=%t %s -I %S/Inputs -isysroot /tmp/.. -I %t -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -debug-info-kind=limited -fmodules -DGREETING="Hello World" -UNDEBUG -fimplicit-module-maps -fmodules-cache-path=%t %s -I %S/Inputs -isysroot /tmp/.. -I %t -emit-llvm -o - | FileCheck %s --check-prefix=NOIMPORT
+
+// NOIMPORT-NOT: !DIImportedEntity
+// NOIMPORT-NOT: !DIModule
+
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -debug-info-kind=limited -fmodules -DGREETING="Hello World" -UNDEBUG -fimplicit-module-maps -fmodules-cache-path=%t %s -I %S/Inputs -isysroot /tmp/.. -I %t -emit-llvm -debugger-tuning=lldb -o - | FileCheck %s
// CHECK: ![[CU:.*]] = distinct !DICompileUnit
@import DebugObjC;
// CHECK: !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: ![[CU]],
-// CHECK-SAME: entity: ![[MODULE:.*]], line: 5)
+// CHECK-SAME: entity: ![[MODULE:.*]], line: [[@LINE-2]])
// CHECK: ![[MODULE]] = !DIModule(scope: null, name: "DebugObjC",
// CHECK-SAME: configMacros: "\22-DGREETING=Hello World\22 \22-UNDEBUG\22",
// CHECK-SAME: includePath: "{{.*}}test{{.*}}Modules{{.*}}Inputs",
diff --git a/test/Modules/embed-files-compressed.cpp b/test/Modules/embed-files-compressed.cpp
new file mode 100644
index 000000000000..cf33a662f91f
--- /dev/null
+++ b/test/Modules/embed-files-compressed.cpp
@@ -0,0 +1,23 @@
+// REQUIRES: zlib
+// REQUIRES: shell
+//
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo '//////////////////////////////////////////////////////////////////////' > %t/a.h
+// RUN: cat %t/a.h %t/a.h %t/a.h %t/a.h > %t/b.h
+// RUN: cat %t/b.h %t/b.h %t/b.h %t/b.h > %t/a.h
+// RUN: cat %t/a.h %t/a.h %t/a.h %t/a.h > %t/b.h
+// RUN: cat %t/b.h %t/b.h %t/b.h %t/b.h > %t/a.h
+// RUN: cat %t/a.h %t/a.h %t/a.h %t/a.h > %t/b.h
+// RUN: cat %t/b.h %t/b.h %t/b.h %t/b.h > %t/a.h
+// RUN: cat %t/a.h %t/a.h %t/a.h %t/a.h > %t/b.h
+// RUN: cat %t/b.h %t/b.h %t/b.h %t/b.h > %t/a.h
+// RUN: echo 'module a { header "a.h" }' > %t/modulemap
+//
+// RUN: %clang_cc1 -fmodules -I%t -fmodules-cache-path=%t -fmodule-name=a -emit-module %t/modulemap -fmodules-embed-all-files -o %t/a.pcm
+//
+// The above embeds ~4.5MB of highly-predictable /s and \ns into the pcm file.
+// Check that the resulting file is under 40KB:
+//
+// RUN: wc -c %t/a.pcm | FileCheck --check-prefix=CHECK-SIZE %s
+// CHECK-SIZE: {{(^|[^0-9])[123][0-9][0-9][0-9][0-9]($|[^0-9])}}
diff --git a/test/Modules/embed-files.cpp b/test/Modules/embed-files.cpp
index a1db21852d05..f300558dd7f7 100644
--- a/test/Modules/embed-files.cpp
+++ b/test/Modules/embed-files.cpp
@@ -1,11 +1,17 @@
// RUN: rm -rf %t
// RUN: mkdir %t
-// RUN: echo 'module a { header "a.h" } module b { header "b.h" }' > %t/modulemap
+// RUN: echo 'module a { header "a.h" header "x.h" } module b { header "b.h" }' > %t/modulemap
// RUN: echo 'extern int t;' > %t/t.h
// RUN: echo '#include "t.h"' > %t/a.h
// RUN: echo '#include "t.h"' > %t/b.h
+// RUN: echo '#include "t.h"' > %t/x.h
// RUN: %clang_cc1 -fmodules -I%t -fmodules-cache-path=%t -fmodule-map-file=%t/modulemap -fmodules-embed-all-files %s -verify
+//
+// RUN: %clang_cc1 -fmodules -I%t -fmodules-embed-all-files %t/modulemap -fmodule-name=a -x c++ -emit-module -o %t/a.pcm
+// RUN: %clang_cc1 -fmodules -I%t -fmodules-embed-all-files %t/modulemap -fmodule-name=b -x c++ -emit-module -o %t/b.pcm
+// RUN: rm %t/x.h
+// RUN: %clang_cc1 -fmodules -I%t -fmodule-map-file=%t/modulemap -fmodule-file=%t/a.pcm -fmodule-file=%t/b.pcm %s -verify
#include "a.h"
char t; // expected-error {{different type}}
// expected-note@t.h:1 {{here}}
diff --git a/test/Modules/explicit-build-flags.cpp b/test/Modules/explicit-build-flags.cpp
index 6ced215a06d1..61300435e2cd 100644
--- a/test/Modules/explicit-build-flags.cpp
+++ b/test/Modules/explicit-build-flags.cpp
@@ -7,8 +7,7 @@
// Can use the module.
// RUN: %clang_cc1 -fmodules -DFOO=1 -x c++ -fmodule-map-file=%t/map -fmodule-file=%t/tmp.pcm -verify -I%t %s
-// Can use the module if an input file is newer. (This happens on
-// remote file systems.)
+// Can use the module if an input file is newer. (This happens on remote file systems.)
// RUN: sleep 1
// RUN: touch %t/tmp.h
// RUN: %clang_cc1 -fmodules -DFOO=1 -x c++ -fmodule-map-file=%t/map -fmodule-file=%t/tmp.pcm -verify -I%t %s
@@ -23,6 +22,22 @@
// Can use the module if -I flags change.
// RUN: %clang_cc1 -fmodules -DBAR=2 -I. -x c++ -fmodule-map-file=%t/map -fmodule-file=%t/tmp.pcm -verify -I%t %s
+// Can use the module if -fPIC/-fPIE flags change.
+// RUN: %clang_cc1 -fmodules -DBAR=2 -pic-level 2 -x c++ -fmodule-map-file=%t/map -fmodule-file=%t/tmp.pcm -verify -I%t %s
+// RUN: %clang_cc1 -fmodules -DBAR=2 -pic-level 1 -pic-is-pie -x c++ -fmodule-map-file=%t/map -fmodule-file=%t/tmp.pcm -verify -I%t %s
+
+// Can use the module if -static flag changes.
+// RUN: %clang_cc1 -fmodules -DBAR=2 -static-define -x c++ -fmodule-map-file=%t/map -fmodule-file=%t/tmp.pcm -verify -I%t %s
+
+// Can use the module if -fsanitize= flags change.
+// RUN: %clang_cc1 -fmodules -DBAR=2 -fsanitize=address -x c++ -fmodule-map-file=%t/map -fmodule-file=%t/tmp.pcm -verify -I%t %s
+//
+// RUN: %clang_cc1 -fmodules -DFOO=1 -fsanitize=address -x c++ -fmodule-name=tmp %t/map -emit-module -o %t/tmp-san.pcm
+// RUN: %clang_cc1 -fmodules -DBAR=2 -x c++ -fmodule-map-file=%t/map -fmodule-file=%t/tmp-san.pcm -verify -I%t %s
+
+// -fno-assume-sane-operator-new is implied by the driver -fsanitize=address flag.
+// RUN: %clang_cc1 -fmodules -DBAR=2 -fno-assume-sane-operator-new -x c++ -fmodule-map-file=%t/map -fmodule-file=%t/tmp.pcm -verify -I%t %s
+
// Can use the module if -O flags change.
// RUN: %clang_cc1 -fmodules -DBAR=2 -Os -x c++ -fmodule-map-file=%t/map -fmodule-file=%t/tmp.pcm -verify -I%t %s
//
diff --git a/test/Modules/explicit-build-missing-files.cpp b/test/Modules/explicit-build-missing-files.cpp
index 1ee65d9c5e0f..e36b5051e831 100644
--- a/test/Modules/explicit-build-missing-files.cpp
+++ b/test/Modules/explicit-build-missing-files.cpp
@@ -3,7 +3,7 @@
// RUN: echo 'extern int a; template<typename T> int a2 = T::error;' > %t/a.h
// RUN: echo 'extern int b;' > %t/b.h
// RUN: echo 'extern int c = 0;' > %t/c.h
-// RUN: echo 'module a { header "a.h" header "b.h" header "c.h" }' > %t/modulemap
+// RUN: echo 'module a { module aa { header "a.h" header "b.h" header "c.h" } }' > %t/modulemap
// RUN: echo 'module other {}' > %t/other.modulemap
// We lazily check that the files referenced by an explicitly-specified .pcm
@@ -18,7 +18,7 @@
// RUN: -fmodules-embed-all-files
// RUN: %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm %s
// RUN: not %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm %s -DERRORS 2>&1 | FileCheck %s
-// RUN: rm %t/modulemap
+// RUN: mv %t/modulemap %t/modulemap.moved
// RUN: %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm %s
// RUN: not %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm %s -DERRORS 2>&1 | FileCheck %s
// RUN: rm %t/other.modulemap
@@ -32,6 +32,9 @@
// RUN: %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm %s
// RUN: %clang_cc1 -fmodules -I %t -fmodule-file=%t/b.pcm %s
// RUN: not %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm %s -DERRORS 2>&1 | FileCheck %s --check-prefix=MISSING-B
+// RUN: %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm -fmodule-map-file=%t/modulemap.moved %s
+// RUN: not %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm -fmodule-map-file=%t/modulemap.moved -std=c++1z %s
+// RUN: %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm -fmodule-map-file=%t/modulemap.moved -std=c++1z -Wno-module-file-config-mismatch %s -Db=a
// RUN: rm %t/a.h
// RUN: %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm %s -verify
// RUN: %clang_cc1 -fmodules -I %t -fmodule-file=%t/b.pcm %s -verify
diff --git a/test/Modules/explicit-build.cpp b/test/Modules/explicit-build.cpp
index 2a5b70dce6cf..a6f6a6268c15 100644
--- a/test/Modules/explicit-build.cpp
+++ b/test/Modules/explicit-build.cpp
@@ -143,7 +143,7 @@
// -------------------------------
// Try to import a PCH with -fmodule-file=
// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
-// RUN: -fmodule-name=a -emit-pch %S/Inputs/explicit-build/a.h -o %t/a.pch \
+// RUN: -fmodule-name=a -emit-pch %S/Inputs/explicit-build/a.h -o %t/a.pch -DBUILDING_A_PCH \
// RUN: 2>&1 | FileCheck --check-prefix=CHECK-NO-IMPLICIT-BUILD %s --allow-empty
//
// RUN: not %clang_cc1 -x c++ -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
diff --git a/test/Modules/getSourceDescriptor-crash.cpp b/test/Modules/getSourceDescriptor-crash.cpp
new file mode 100644
index 000000000000..84e527aef91b
--- /dev/null
+++ b/test/Modules/getSourceDescriptor-crash.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -I %S/Inputs/getSourceDescriptor-crash -S -emit-llvm -debug-info-kind=limited -debugger-tuning=lldb -fimplicit-module-maps %s -o - | FileCheck %s
+
+#include "h1.h"
+#include "h1.h"
+
+// CHECK: DIImportedEntity
+// CHECK-SAME: entity: ![[ENTITY:[0-9]+]]
+// CHECK: ![[ENTITY]] = !DIModule
+// CHECK-SAME: name: "foo"
diff --git a/test/Modules/implementation-of-module.m b/test/Modules/implementation-of-module.m
index 37e2cfbe30fd..712f12c56549 100644
--- a/test/Modules/implementation-of-module.m
+++ b/test/Modules/implementation-of-module.m
@@ -1,7 +1,3 @@
-// RUN: not %clang_cc1 -fmodule-implementation-of Foo -fmodule-name=Bar %s 2>&1 \
-// RUN: | FileCheck -check-prefix=CHECK-IMPL-OF-ERR %s
-// CHECK-IMPL-OF-ERR: conflicting module names specified: '-fmodule-name=Bar' and '-fmodule-implementation-of Foo'
-
// RUN: rm -rf %t
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -w -Werror=auto-import %s -I %S/Inputs \
// RUN: -fmodule-implementation-of category_right -fsyntax-only
diff --git a/test/Modules/implicit-build-config-out-of-date.m b/test/Modules/implicit-build-config-out-of-date.m
new file mode 100644
index 000000000000..c8c02ff0a808
--- /dev/null
+++ b/test/Modules/implicit-build-config-out-of-date.m
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t
+// Use -DA=0 so that there is at least one preprocessor option serialized after the diagnostic options.
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I %S/Inputs %s -DA=0 -Rmodule-build -verify
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I %S/Inputs %s -DA=0 -Werror -Rmodule-build -verify
+
+@import category_top; // expected-remark {{building module}} expected-remark {{finished building}}
diff --git a/test/Modules/import-self.m b/test/Modules/import-self.m
index aa7437132372..e59801592450 100644
--- a/test/Modules/import-self.m
+++ b/test/Modules/import-self.m
@@ -6,6 +6,6 @@
// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t \
// RUN: -I %S/Inputs/submodules -fmodule-name=import_self %s \
// RUN: 2>&1 | FileCheck -check-prefix=CHECK-fmodule-name %s
-// CHECK-fmodule-name: import of module 'import_self.b' appears within same top-level module 'import_self'
+// CHECK-fmodule-name: @import of module 'import_self.b' in implementation of 'import_self'
@import import_self.b;
diff --git a/test/Modules/include-own-headers.m b/test/Modules/include-own-headers.m
new file mode 100644
index 000000000000..a5a85312ec3d
--- /dev/null
+++ b/test/Modules/include-own-headers.m
@@ -0,0 +1,4 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodule-name=Module -fimplicit-module-maps -fmodules-cache-path=%t -Werror=non-modular-include-in-framework-module -F%S/Inputs -I%S -fsyntax-only %s
+#include "Module/Module.h"
+#include "Inputs/non-module.h"
diff --git a/test/Modules/merge-decl-context.cpp b/test/Modules/merge-decl-context.cpp
index 55219ed587b0..5dbf3d1bd95f 100644
--- a/test/Modules/merge-decl-context.cpp
+++ b/test/Modules/merge-decl-context.cpp
@@ -18,7 +18,13 @@
// RUN: -fmodule-map-file=%S/Inputs/merge-decl-context/merge-decl-context.modulemap -I%S/Inputs \
// RUN: -emit-llvm -o %t/test.o %s
+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t \
+// RUN: -fmodule-map-file=%S/Inputs/merge-decl-context/merge-decl-context.modulemap -I%S/Inputs \
+// RUN: -emit-llvm -o %t/test.o -DNO_TEXTUAL_INCLUSION %s
+
+#ifndef NO_TEXTUAL_INCLUSION
#include "Inputs/merge-decl-context/a.h"
+#endif
#include "Inputs/merge-decl-context/b.h"
#include "Inputs/merge-decl-context/c.h"
#include "Inputs/merge-decl-context/d.h"
@@ -26,3 +32,5 @@
void t() {
ff(42);
}
+
+static_assert(Aggregate{.member = 1}.member == 1, "");
diff --git a/test/Modules/method_pool_write.m b/test/Modules/method_pool_write.m
new file mode 100644
index 000000000000..b7f8ac64b4d3
--- /dev/null
+++ b/test/Modules/method_pool_write.m
@@ -0,0 +1,11 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -fsyntax-only -I %S/Inputs %s -verify
+// expected-no-diagnostics
+
+@import MethodPoolCombined;
+@import MethodPoolString2;
+
+void message_kindof_object(__kindof S2 *kindof_S2) {
+ [kindof_S2 stringValue];
+}
+
diff --git a/test/Modules/minimal-identifier-tables.cpp b/test/Modules/minimal-identifier-tables.cpp
new file mode 100644
index 000000000000..0674746e07fe
--- /dev/null
+++ b/test/Modules/minimal-identifier-tables.cpp
@@ -0,0 +1,10 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo 'extern int some_long_variable_name;' > %t/x.h
+// RUN: echo 'extern int some_long_variable_name;' > %t/y.h
+// RUN: echo 'module X { header "x.h" } module Y { header "y.h" }' > %t/map
+// RUN: %clang_cc1 -fmodules -x c++ -fmodule-name=X %t/map -emit-module -o %t/x.pcm
+// RUN: %clang_cc1 -fmodules -x c++ -fmodule-name=Y %t/map -fmodule-file=%t/x.pcm -emit-module -o %t/y.pcm
+// RUN: cat %t/y.pcm | FileCheck %s
+//
+// CHECK-NOT: some_long_variable_name
diff --git a/test/Modules/no-implicit-builds.cpp b/test/Modules/no-implicit-builds.cpp
index 374ed5e4181e..fa4d5cb3c530 100644
--- a/test/Modules/no-implicit-builds.cpp
+++ b/test/Modules/no-implicit-builds.cpp
@@ -1,5 +1,9 @@
// RUN: rm -rf %t
+// RUN: %clang -x c++ -std=c++11 -fmodules -fno-implicit-modules /dev/null -### \
+// RUN: 2>&1 | FileCheck --check-prefix=CHECK-NO-MODULE-CACHE %s
+// CHECK-NO-MODULE-CACHE-NOT: -fmodules-cache-path
+
// Produce an error if a module is needed, but not found.
// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t \
// RUN: -fmodule-map-file=%S/Inputs/no-implicit-builds/b.modulemap \
diff --git a/test/Modules/objc-categories.m b/test/Modules/objc-categories.m
index e8549fabb50e..42baf352fbf5 100644
--- a/test/Modules/objc-categories.m
+++ b/test/Modules/objc-categories.m
@@ -9,7 +9,7 @@
@import category_bottom;
// expected-note@Inputs/category_left.h:14 {{previous definition}}
-// expected-warning@Inputs/category_right.h:11 {{duplicate definition of category}}
+// expected-warning@Inputs/category_right.h:12 {{duplicate definition of category}}
// expected-note@Inputs/category_top.h:1 {{receiver is instance of class declared here}}
@interface Foo(Source)
diff --git a/test/Modules/parse-attributes.modulemap b/test/Modules/parse-attributes.modulemap
new file mode 100644
index 000000000000..0d18325580a7
--- /dev/null
+++ b/test/Modules/parse-attributes.modulemap
@@ -0,0 +1,12 @@
+// RUN: rm -rf %t.modules
+// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t.modules \
+// RUN: -fmodule-map-file=%s -I%S -include "Inputs/empty.h" \
+// RUN: -fsyntax-only -x c++ /dev/null 2>&1 | FileCheck %s
+
+// CHECK: error: expected ']' to close attribute
+// CHECK-NOT: error: expected '{' to start module 'A'
+
+module A [system {
+ header "Inputs/empty.h"
+ private header "Inputs/empty.h"
+}
diff --git a/test/Modules/pch-module-macro.m b/test/Modules/pch-module-macro.m
new file mode 100644
index 000000000000..cc9f68737451
--- /dev/null
+++ b/test/Modules/pch-module-macro.m
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -emit-pch -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -o %t.pch -I %S/Inputs -x objective-c-header %S/Inputs/pch-import-module-with-macro.pch
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -fsyntax-only -I %S/Inputs -include-pch %t.pch %s -verify
+// expected-no-diagnostics
+
+int test(int x) {
+ return my_fabs(x) + fabs(x);
+}
+
diff --git a/test/Modules/pr21547.cpp b/test/Modules/pr21547.cpp
new file mode 100644
index 000000000000..c6275b4cc7f1
--- /dev/null
+++ b/test/Modules/pr21547.cpp
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -I%S/Inputs/PR21547 -verify %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I%S/Inputs/PR21547 -verify %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I%S/Inputs/PR21547 -emit-llvm-only %s
+
+#include "Inputs/PR21547/FirstHeader.h"
+
+//expected-no-diagnostics
diff --git a/test/Modules/pr24954.cpp b/test/Modules/pr24954.cpp
new file mode 100644
index 000000000000..407ee06e4025
--- /dev/null
+++ b/test/Modules/pr24954.cpp
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -I%S/Inputs/PR24954 -verify %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I%S/Inputs/PR24954 -verify %s
+
+#include "A.h"
+
+// expected-no-diagnostics
diff --git a/test/Modules/pr25501.cpp b/test/Modules/pr25501.cpp
new file mode 100644
index 000000000000..18002d6dff3f
--- /dev/null
+++ b/test/Modules/pr25501.cpp
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -std=c++11 -fmodules -fmodule-map-file=%S/Inputs/PR25501/module.modulemap -fmodules-cache-path=%t -I%S/Inputs/PR25501 -verify %s
+
+#include "a2.h"
+#include "b.h"
+
+auto use = aaa;
+
+// expected-no-diagnostics
diff --git a/test/Modules/pr26014.cpp b/test/Modules/pr26014.cpp
new file mode 100644
index 000000000000..f9ebd4e1dd7a
--- /dev/null
+++ b/test/Modules/pr26014.cpp
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -I%S/Inputs/PR26014 -verify %s
+// RUN: %clang_cc1 -fmodules -fmodule-map-file=%S/Inputs/PR26014/module.modulemap -fmodules-cache-path=%t -I%S/Inputs/PR26014 -verify %s
+
+#include "A.h"
+
+// expected-no-diagnostics
diff --git a/test/Modules/pr26179.cpp b/test/Modules/pr26179.cpp
new file mode 100644
index 000000000000..f25f1ce24bda
--- /dev/null
+++ b/test/Modules/pr26179.cpp
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -I%S/Inputs/PR26179 -verify %s
+// RUN: %clang_cc1 -fmodules -fmodule-map-file=%S/Inputs/PR26179/module.modulemap -fmodules-cache-path=%t -I%S/Inputs/PR26179 -verify %s
+
+#include "A.h"
+
+// expected-no-diagnostics
diff --git a/test/Modules/pr27041.cpp b/test/Modules/pr27041.cpp
new file mode 100644
index 000000000000..9d06468b97bd
--- /dev/null
+++ b/test/Modules/pr27041.cpp
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -std=c++11 -I%S/Inputs/PR27041 -verify %s
+// RUN: %clang_cc1 -std=c++11 -fmodules -fmodule-map-file=%S/Inputs/PR27041/module.modulemap -fmodules-cache-path=%t -I%S/Inputs/PR27041 -verify %s
+
+#include "Rtypes.h"
+
+// expected-no-diagnostics
diff --git a/test/Modules/pr27186.cpp b/test/Modules/pr27186.cpp
new file mode 100644
index 000000000000..02a8fe5b00e8
--- /dev/null
+++ b/test/Modules/pr27186.cpp
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -std=c++11 -I%S/Inputs/PR27186 -I%S/Inputs/PR27186/subdir/ -verify %s
+// RUN: %clang_cc1 -nostdsysteminc -std=c++11 -fmodules -fmodule-map-file=%S/Inputs/PR27186/module.modulemap -fmodules-cache-path=%t -I%S/Inputs/PR27186/ -verify %s
+
+#include "Rtypes.h"
+
+// expected-no-diagnostics
diff --git a/test/Modules/pr27401.cpp b/test/Modules/pr27401.cpp
new file mode 100644
index 000000000000..7d5479cb9243
--- /dev/null
+++ b/test/Modules/pr27401.cpp
@@ -0,0 +1,38 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -std=c++11 -I%S/Inputs/PR27401 -verify %s
+// RUN: %clang_cc1 -std=c++11 -fmodules -fmodule-map-file=%S/Inputs/PR27401/module.modulemap -fmodules-cache-path=%t -I%S/Inputs/PR27401 -verify %s
+
+#include "a.h"
+#define _LIBCPP_VECTOR
+template <class, class _Allocator>
+class __vector_base {
+protected:
+ _Allocator __alloc() const;
+ __vector_base(_Allocator);
+};
+
+template <class _Tp, class _Allocator = allocator>
+class vector : __vector_base<_Tp, _Allocator> {
+public:
+ vector() noexcept(is_nothrow_default_constructible<_Allocator>::value);
+ vector(const vector &);
+ vector(vector &&)
+ noexcept(is_nothrow_move_constructible<_Allocator>::value);
+};
+
+template <class _Tp, class _Allocator>
+vector<_Tp, _Allocator>::vector(const vector &__x) : __vector_base<_Tp, _Allocator>(__x.__alloc()) {}
+
+ struct CommentOptions {
+ vector<char> ParseAllComments;
+ CommentOptions() {}
+ };
+ struct PrintingPolicy {
+ PrintingPolicy(CommentOptions LO) : LangOpts(LO) {}
+ CommentOptions LangOpts;
+ };
+
+#include "b.h"
+CommentOptions fn1() { return fn1(); }
+
+// expected-no-diagnostics
diff --git a/test/Modules/pr27513.cpp b/test/Modules/pr27513.cpp
new file mode 100644
index 000000000000..28fbe5bd8255
--- /dev/null
+++ b/test/Modules/pr27513.cpp
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -std=c++11 -I%S/Inputs/PR27513 -verify %s
+// RUN: %clang_cc1 -std=c++11 -fmodules -fmodule-map-file=%S/Inputs/PR27513/module.modulemap -fmodules-cache-path=%t -I%S/Inputs/PR27513 -verify %s
+
+#include "Inputs/PR27513/a.h"
+
+//expected-no-diagnostics
diff --git a/test/Modules/pr27739.cpp b/test/Modules/pr27739.cpp
new file mode 100644
index 000000000000..b27dc1b09371
--- /dev/null
+++ b/test/Modules/pr27739.cpp
@@ -0,0 +1,12 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -std=c++11 -internal-externc-isystem %S/Inputs/PR27739 -verify %s
+// RUN: %clang_cc1 -std=c++11 -fmodules -fmodule-map-file=%S/Inputs/PR27739/module.modulemap -fmodules-cache-path=%t -internal-externc-isystem %S/Inputs/PR27739/ -verify %s
+
+#include "DataInputHandler.h"
+
+void DataInputHandler::AddTree() {
+ fInputTrees[(char*)""];
+ fExplicitTrainTest[(char*)""];
+}
+
+// expected-no-diagnostics
diff --git a/test/Modules/pr27754.cpp b/test/Modules/pr27754.cpp
new file mode 100644
index 000000000000..048259542948
--- /dev/null
+++ b/test/Modules/pr27754.cpp
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -std=c++11 -I%S/Inputs/PR27754 -verify %s
+// RUN: %clang_cc1 -std=c++11 -fmodules -fmodule-map-file=%S/Inputs/PR27754/module.modulemap -fmodules-cache-path=%t -I%S/Inputs/PR27754/ -verify %s
+
+#include "TMetaUtils.h"
+
+// expected-no-diagnostics
diff --git a/test/Modules/pr27890.cpp b/test/Modules/pr27890.cpp
new file mode 100644
index 000000000000..8bb9a9fd5c91
--- /dev/null
+++ b/test/Modules/pr27890.cpp
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -std=c++11 -I%S/Inputs/PR27890 -verify %s
+// RUN: %clang_cc1 -std=c++11 -fmodules -fmodule-map-file=%S/Inputs/PR27890/module.modulemap -fmodules-cache-path=%t -I%S/Inputs/PR27890 -verify %s
+
+#include "a.h"
+enum ActionType {};
+opt<ActionType> a(values(""));
+
+// expected-no-diagnostics \ No newline at end of file
diff --git a/test/Modules/preprocess.cpp b/test/Modules/preprocess.cpp
new file mode 100644
index 000000000000..0615331c8bd7
--- /dev/null
+++ b/test/Modules/preprocess.cpp
@@ -0,0 +1,24 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -x c++ -E %s | \
+// RUN: FileCheck -strict-whitespace %s --check-prefix=CHECK --check-prefix=CXX --check-prefix=CXX-DASHE
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -x objective-c -E %s | \
+// RUN: FileCheck -strict-whitespace %s --check-prefix=CHECK --check-prefix=OBJC
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -x c++ -E -frewrite-includes %s | \
+// RUN: FileCheck -strict-whitespace %s --check-prefix=CHECK --check-prefix=CXX
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -x objective-c -E -frewrite-includes %s | \
+// RUN: FileCheck -strict-whitespace %s --check-prefix=CHECK --check-prefix=OBJC
+#include "dummy.h"
+#include "dummy.h"
+foo bar baz
+
+// The weird {{ }} here is to prevent the -frewrite-includes test from matching its own CHECK lines.
+
+// CXX: #include{{ }}"dummy.h"
+// CXX-DASHE-SAME: /* clang -E: implicit import for module dummy */
+// CXX: #include{{ }}"dummy.h"
+// CXX-DASHE-SAME: /* clang -E: implicit import for module dummy */
+// CXX: foo bar baz
+
+// OBJC: @import{{ }}dummy; /* clang
+// OBJC: @import{{ }}dummy; /* clang
+// OBJC: foo bar baz
diff --git a/test/Modules/submodules-merge-defs.cpp b/test/Modules/submodules-merge-defs.cpp
index 23d1f5cfb12b..4ab822a022bd 100644
--- a/test/Modules/submodules-merge-defs.cpp
+++ b/test/Modules/submodules-merge-defs.cpp
@@ -58,6 +58,11 @@ G::A pre_ga // expected-error +{{must be imported}}
decltype(G::h) pre_gh = G::h; // expected-error +{{must be imported}}
// expected-note@defs.h:51 +{{here}}
+int pre_h = H(); // expected-error +{{must be imported}}
+// expected-note@defs.h:56 +{{here}}
+using pre_i = I<>; // expected-error +{{must be imported}}
+// expected-note@defs.h:57 +{{here}}
+
J<> pre_j; // expected-error {{declaration of 'J' must be imported}}
#ifdef IMPORT_USE_2
// expected-error-re@-2 {{default argument of 'J' must be imported from one of {{.*}}stuff.use{{.*}}stuff.use-2}}
@@ -99,6 +104,8 @@ int post_ff = F<char>().f();
int post_fg = F<char>().g<int>();
G::A post_ga = G::a;
decltype(G::h) post_gh = G::h;
+int post_h = H();
+using post_i = I<>;
J<> post_j;
template<typename T, int N, template<typename> class K> struct J;
J<> post_j2;
diff --git a/test/Modules/suggest-include.cpp b/test/Modules/suggest-include.cpp
new file mode 100644
index 000000000000..e10c3f38aba2
--- /dev/null
+++ b/test/Modules/suggest-include.cpp
@@ -0,0 +1,33 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs/suggest-include %s -verify
+
+#include "empty.h" // import the module file
+
+// expected-note@usetextual1.h:2 {{previous}}
+// expected-note@textual2.h:1 {{previous}}
+// expected-note@textual3.h:1 {{previous}}
+// expected-note@textual4.h:1 {{previous}}
+// expected-note@textual5.h:1 {{previous}}
+// expected-note@private1.h:1 {{previous}}
+// expected-note@private2.h:1 {{previous}}
+// expected-note@private3.h:1 {{previous}}
+
+void f() {
+ (void)::usetextual1; // expected-error {{missing '#include "usetextual1.h"'}}
+ (void)::usetextual2; // expected-error {{missing '#include "usetextual2.h"'}}
+ (void)::textual3; // expected-error-re {{{{^}}missing '#include "usetextual3.h"'}}
+ // Don't suggest a #include that includes the entity via a path that leaves
+ // the module. In that case we can't be sure that we've picked the right header.
+ (void)::textual4; // expected-error-re {{{{^}}declaration of 'textual4'}}
+ (void)::textual5; // expected-error-re {{{{^}}declaration of 'textual5'}}
+
+ // Don't suggest #including a private header.
+ // FIXME: We could suggest including "useprivate1.h" here, as it's the only
+ // public way to get at this declaration.
+ (void)::private1; // expected-error-re {{{{^}}declaration of 'private1'}}
+ // FIXME: Should we be suggesting an import at all here? Should declarations
+ // in private headers be visible when the surrounding module is imported?
+ (void)::private2; // expected-error-re {{{{^}}declaration of 'private2'}}
+ // Even if we suggest an include for private1, we should not do so here.
+ (void)::private3; // expected-error-re {{{{^}}declaration of 'private3'}}
+}
diff --git a/test/Modules/typo.m b/test/Modules/typo.m
new file mode 100644
index 000000000000..7e5108df6bed
--- /dev/null
+++ b/test/Modules/typo.m
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -x objective-c-header %S/Inputs/typo.h -emit-pch -o %t.pch
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -include-pch %t.pch %s -verify
+
+void test() {
+ [Nsstring alloc]; // expected-error {{unknown receiver 'Nsstring'; did you mean 'NSString'}}
+ // expected-note@typo.h:* {{here}}
+}
diff --git a/test/Modules/use-after-free.m b/test/Modules/use-after-free.m
new file mode 100644
index 000000000000..fa7200933afd
--- /dev/null
+++ b/test/Modules/use-after-free.m
@@ -0,0 +1,24 @@
+// RUN: rm -rf %t
+
+// Here, we build the module without "non-modular-include-in-framework-module".
+// RUN: echo '@import UseAfterFreePublic;' | \
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps \
+// RUN: -fmodules-cache-path=%t -isystem %S/Inputs/UseAfterFree/ -fsyntax-only \
+// RUN: -x objective-c -
+
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps \
+// RUN: -fmodules-cache-path=%t -isystem %S/Inputs/UseAfterFree/ -fsyntax-only \
+// RUN: -Wnon-modular-include-in-framework-module -Werror=non-modular-include-in-framework-module \
+// RUN: -x objective-c %s -verify
+// expected-no-diagnostics
+
+// Here, we load the module UseAfterFreePublic, it is treated as a system module,
+// we ignore the inconsistency for "non-modular-include-in-framework-module".
+@import UseAfterFreePublic;
+
+// We start a thread to build the module for UseAfterFreePrivate.h. In the thread,
+// we load UseAfterFreePublic and should treat it as a system module as well.
+// If not, we will invalidate UseAfterFreePublic because of the inconsistency
+// for "non-modular-include-in-framework-module", and have a use-after-free error
+// of the FileEntry.
+#import <UseAfterFreePrivate.h>