summaryrefslogtreecommitdiffstats
path: root/test/Modules
diff options
context:
space:
mode:
Diffstat (limited to 'test/Modules')
-rw-r--r--test/Modules/DebugInfoSubmoduleImport.c15
-rw-r--r--test/Modules/DebugInfoSubmodules.c18
-rw-r--r--test/Modules/DebugInfoTransitiveImport.m22
-rw-r--r--test/Modules/ExtDebugInfo.cpp72
-rw-r--r--test/Modules/ExtDebugInfo.m36
-rw-r--r--test/Modules/Inputs/AutolinkTBD.framework/AutolinkTBD.tbd1
-rw-r--r--test/Modules/Inputs/AutolinkTBD.framework/Headers/AutolinkTBD.h1
-rw-r--r--test/Modules/Inputs/DebugCXX.h52
-rw-r--r--test/Modules/Inputs/DebugModule.h1
-rw-r--r--test/Modules/Inputs/DebugObjC.h24
-rw-r--r--test/Modules/Inputs/DebugSubmoduleA.h3
-rw-r--r--test/Modules/Inputs/DebugSubmoduleB.h3
-rw-r--r--test/Modules/Inputs/ExtensionTestA.h1
-rw-r--r--test/Modules/Inputs/System/usr/include/assert.h2
-rw-r--r--test/Modules/Inputs/System/usr/include/module.map22
-rw-r--r--test/Modules/Inputs/System/usr/include/tcl-private/header.h2
-rw-r--r--test/Modules/Inputs/auto-import-unavailable/missing_header/not_missing.h1
-rw-r--r--test/Modules/Inputs/auto-import-unavailable/missing_requirement.h1
-rw-r--r--test/Modules/Inputs/auto-import-unavailable/module.modulemap19
-rw-r--r--test/Modules/Inputs/auto-import-unavailable/nonrequired_missing_header/not_missing.h1
-rw-r--r--test/Modules/Inputs/auto-import-unavailable/nonrequired_missing_header/requires_feature_you_dont_have.h1
-rw-r--r--test/Modules/Inputs/available-is-better/available-is-better.h2
-rw-r--r--test/Modules/Inputs/available-is-better/module.modulemap17
-rw-r--r--test/Modules/Inputs/builtin_sub.h1
-rw-r--r--test/Modules/Inputs/declare-use/module.map2
-rw-r--r--test/Modules/Inputs/elaborated-type-structs.h3
-rw-r--r--test/Modules/Inputs/explicit-build-overlap/a.h1
-rw-r--r--test/Modules/Inputs/explicit-build-overlap/b.h1
-rw-r--r--test/Modules/Inputs/explicit-build-overlap/def.map2
-rw-r--r--test/Modules/Inputs/explicit-build-overlap/use.map3
-rw-r--r--test/Modules/Inputs/internal-constants/a.h3
-rw-r--r--test/Modules/Inputs/internal-constants/b.h3
-rw-r--r--test/Modules/Inputs/internal-constants/c.h3
-rw-r--r--test/Modules/Inputs/internal-constants/const.h3
-rw-r--r--test/Modules/Inputs/internal-constants/module.modulemap6
-rw-r--r--test/Modules/Inputs/libstdcxx-ambiguous-internal/a.h5
-rw-r--r--test/Modules/Inputs/libstdcxx-ambiguous-internal/b.h4
-rw-r--r--test/Modules/Inputs/libstdcxx-ambiguous-internal/c.h4
-rw-r--r--test/Modules/Inputs/libstdcxx-ambiguous-internal/d.h4
-rw-r--r--test/Modules/Inputs/libstdcxx-ambiguous-internal/module.modulemap6
-rw-r--r--test/Modules/Inputs/macro-reexport/module.modulemap1
-rw-r--r--test/Modules/Inputs/misplaced/misplaced-a.h5
-rw-r--r--test/Modules/Inputs/misplaced/misplaced-b.h1
-rw-r--r--test/Modules/Inputs/misplaced/misplaced.modulemap8
-rw-r--r--test/Modules/Inputs/module-map-path-hash/a.h2
-rw-r--r--test/Modules/Inputs/module-map-path-hash/module.modulemap3
-rw-r--r--test/Modules/Inputs/module.map50
-rw-r--r--test/Modules/Inputs/no-linkage/decls.h11
-rw-r--r--test/Modules/Inputs/no-linkage/empty.h0
-rw-r--r--test/Modules/Inputs/no-linkage/module.modulemap1
-rw-r--r--test/Modules/Inputs/private3/private.h7
-rw-r--r--test/Modules/Inputs/private3/public.h11
-rw-r--r--test/Modules/Inputs/stress1/merge00.h4
-rw-r--r--test/Modules/Inputs/stress1/merge_no_reexport.h9
-rw-r--r--test/Modules/Inputs/stress1/module.modulemap1
-rw-r--r--test/Modules/Inputs/submodules-merge-defs/defs.h41
-rw-r--r--test/Modules/Inputs/template-default-args/a.h9
-rw-r--r--test/Modules/Inputs/template-default-args/c.h2
-rw-r--r--test/Modules/Inputs/template-default-args/d.h6
-rw-r--r--test/Modules/Inputs/template-default-args/module.modulemap3
-rw-r--r--test/Modules/Inputs/templates-right.h4
-rw-r--r--test/Modules/Inputs/templates-top.h1
-rw-r--r--test/Modules/Inputs/thread-safety/a.h4
-rw-r--r--test/Modules/Inputs/thread-safety/b.h8
-rw-r--r--test/Modules/Inputs/thread-safety/c.h10
-rw-r--r--test/Modules/Inputs/thread-safety/module.map3
-rw-r--r--test/Modules/Inputs/typedef-tag-hidden.h1
-rw-r--r--test/Modules/Inputs/typedef-tag.h1
-rw-r--r--test/Modules/Inputs/use-builtin.h2
-rw-r--r--test/Modules/Inputs/using-decl-a.h1
-rw-r--r--test/Modules/Inputs/using-decl-b.h27
-rw-r--r--test/Modules/Inputs/using-decl-redecl/a.h2
-rw-r--r--test/Modules/Inputs/using-decl-redecl/b.h3
-rw-r--r--test/Modules/Inputs/using-decl-redecl/c.h2
-rw-r--r--test/Modules/Inputs/using-decl-redecl/module.modulemap3
-rw-r--r--test/Modules/Inputs/va_list/left.h7
-rw-r--r--test/Modules/Inputs/va_list/module.modulemap3
-rw-r--r--test/Modules/Inputs/va_list/right.h7
-rw-r--r--test/Modules/Inputs/va_list/top.h1
-rw-r--r--test/Modules/Inputs/working-dir-test/Test.framework/Headers/Test.h1
-rw-r--r--test/Modules/Inputs/working-dir-test/Test.framework/Modules/module.modulemap6
-rw-r--r--test/Modules/ModuleDebugInfo.cpp44
-rw-r--r--test/Modules/ModuleDebugInfo.m51
-rw-r--r--test/Modules/auto-import-unavailable.cpp47
-rw-r--r--test/Modules/auto-module-import.m19
-rw-r--r--test/Modules/autolinkTBD.m17
-rw-r--r--test/Modules/available-is-better.cpp5
-rw-r--r--test/Modules/builtins.m8
-rw-r--r--test/Modules/compiler_builtins_aarch64.m6
-rw-r--r--test/Modules/cxx-irgen.cpp2
-rw-r--r--test/Modules/cxx-templates.cpp20
-rw-r--r--test/Modules/darwin_specific_modulemap_hacks.m22
-rw-r--r--test/Modules/debug-info-moduleimport.m26
-rw-r--r--test/Modules/decldef.m8
-rw-r--r--test/Modules/dependency-gen-pch.m2
-rw-r--r--test/Modules/dependency-gen.m4
-rw-r--r--test/Modules/dependency-gen.modulemap43
-rw-r--r--test/Modules/elaborated-type-specifier-from-hidden-module.m18
-rw-r--r--test/Modules/embed-files.cpp15
-rw-r--r--test/Modules/empty.modulemap6
-rw-r--r--test/Modules/explicit-build-extra-files.cpp14
-rw-r--r--test/Modules/explicit-build-missing-files.cpp56
-rw-r--r--test/Modules/explicit-build-overlap.cpp14
-rw-r--r--test/Modules/explicit-build.cpp7
-rw-r--r--test/Modules/extensions.c44
-rw-r--r--test/Modules/extern_c.cpp18
-rw-r--r--test/Modules/fatal-module-loader-error.m4
-rw-r--r--test/Modules/hidden-definition.cpp16
-rw-r--r--test/Modules/internal-constants.cpp12
-rw-r--r--test/Modules/libstdcxx-ambiguous-internal.cpp13
-rw-r--r--test/Modules/linkage-merge.cpp4
-rw-r--r--test/Modules/macros.c25
-rw-r--r--test/Modules/malformed.cpp10
-rw-r--r--test/Modules/merge-enumerators.cpp19
-rw-r--r--test/Modules/merge-target-features.cpp9
-rw-r--r--test/Modules/merge-using-decls.cpp2
-rw-r--r--test/Modules/misplaced-1.cpp6
-rw-r--r--test/Modules/misplaced-2.cpp6
-rw-r--r--test/Modules/misplaced-3.cpp6
-rw-r--r--test/Modules/misplaced-4.cpp2
-rw-r--r--test/Modules/misplaced-5.c6
-rw-r--r--test/Modules/module-map-path-hash.cpp10
-rw-r--r--test/Modules/module-private.cpp6
-rw-r--r--test/Modules/modules.idxbin0 -> 404 bytes
-rw-r--r--test/Modules/no-implicit-builds.cpp5
-rw-r--r--test/Modules/no-linkage.cpp56
-rw-r--r--test/Modules/private.modulemap35
-rw-r--r--test/Modules/relative-dep-gen.cpp18
-rw-r--r--test/Modules/stress1.cpp22
-rw-r--r--test/Modules/submodule-visibility-cycles.cpp2
-rw-r--r--test/Modules/submodule-visibility.cpp7
-rw-r--r--test/Modules/submodules-merge-defs.cpp64
-rw-r--r--test/Modules/system_headers.m2
-rw-r--r--test/Modules/target-features.m61
-rw-r--r--test/Modules/template-default-args.cpp18
-rw-r--r--test/Modules/templates.mm2
-rw-r--r--test/Modules/thread-safety.cpp18
-rw-r--r--test/Modules/typedef-tag-not-visible.m8
-rw-r--r--test/Modules/using-decl-redecl.cpp11
-rw-r--r--test/Modules/using-decl.cpp80
-rw-r--r--test/Modules/va_list.cpp8
-rw-r--r--test/Modules/working-dir-flag.m9
142 files changed, 1636 insertions, 105 deletions
diff --git a/test/Modules/DebugInfoSubmoduleImport.c b/test/Modules/DebugInfoSubmoduleImport.c
new file mode 100644
index 0000000..9fb5d9c
--- /dev/null
+++ b/test/Modules/DebugInfoSubmoduleImport.c
@@ -0,0 +1,15 @@
+// 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
+#include "DebugSubmoduleA.h"
+#include "DebugSubmoduleB.h"
+
+// CHECK: !DICompileUnit
+// CHECK-NOT: !DICompileUnit
+// CHECK: !DIModule(scope: ![[PARENT:.*]], name: "DebugSubmoduleA"
+// CHECK: [[PARENT]] = !DIModule(scope: null, name: "DebugSubmodules"
+// CHECK: !DIModule(scope: ![[PARENT]], name: "DebugSubmoduleB"
+// CHECK: !DICompileUnit({{.*}}splitDebugFilename: {{.*}}DebugSubmodules
+// CHECK-SAME: dwoId:
+// CHECK-NOT: !DICompileUnit
diff --git a/test/Modules/DebugInfoSubmodules.c b/test/Modules/DebugInfoSubmodules.c
new file mode 100644
index 0000000..b662a3e
--- /dev/null
+++ b/test/Modules/DebugInfoSubmodules.c
@@ -0,0 +1,18 @@
+// 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 -mllvm -debug-only=pchcontainer -emit-llvm -o %t.ll \
+// RUN: 2>&1 | FileCheck %s
+// REQUIRES: asserts
+#include "DebugSubmoduleA.h"
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "A",
+// CHECK-SAME: scope: ![[SUBMODULEA:[0-9]+]]
+// CHECK: ![[SUBMODULEA]] = !DIModule(scope: ![[PARENT:[0-9]+]],
+// CHECK-SAME: name: "DebugSubmoduleA",
+// CHECK: ![[PARENT]] = !DIModule(scope: null, name: "DebugSubmodules"
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "B",
+// CHECK-SAME: scope: ![[SUBMODULEB:[0-9]+]]
+// CHECK: ![[SUBMODULEB]] = !DIModule(scope: ![[PARENT]],
+// CHECK-SAME: name: "DebugSubmoduleB",
diff --git a/test/Modules/DebugInfoTransitiveImport.m b/test/Modules/DebugInfoTransitiveImport.m
new file mode 100644
index 0000000..206be2e
--- /dev/null
+++ b/test/Modules/DebugInfoTransitiveImport.m
@@ -0,0 +1,22 @@
+// 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
+// REQUIRES: asserts
+
+@import diamond_left;
+
+// Definition of top:
+// CHECK: !DICompileUnit({{.*}}dwoId:
+// CHECK: !DIFile({{.*}}diamond_top.h
+
+// Definition of left:
+// CHECK: !DICompileUnit({{.*}}dwoId:
+// CHECK: !DIFile({{.*}}diamond_left
+// CHECK: !DIImportedEntity(tag: DW_TAG_imported_declaration,
+// CHECK-SAME: entity: ![[MODULE:.*]], line: 3)
+// CHECK: ![[MODULE]] = !DIModule(scope: null, name: "diamond_top"
+
+// Skeleton for top:
+// CHECK: !DICompileUnit({{.*}}splitDebugFilename: {{.*}}diamond_top{{.*}}dwoId:
+
diff --git a/test/Modules/ExtDebugInfo.cpp b/test/Modules/ExtDebugInfo.cpp
new file mode 100644
index 0000000..b255042
--- /dev/null
+++ b/test/Modules/ExtDebugInfo.cpp
@@ -0,0 +1,72 @@
+// RUN: rm -rf %t
+// 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: -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
+// RUN: cat %t-mod.ll | FileCheck %s
+
+// PCH:
+// 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: -triple %itanium_abi_triple \
+// RUN: -include-pch %t.pch %s -emit-llvm -o %t-pch.ll %s
+// RUN: cat %t-pch.ll | FileCheck %s
+
+#ifdef MODULES
+@import DebugCXX;
+#endif
+
+using DebugCXX::Struct;
+
+Struct s;
+DebugCXX::Enum e;
+DebugCXX::Template<long> implicitTemplate;
+DebugCXX::Template<int> explicitTemplate;
+DebugCXX::FloatInstatiation typedefTemplate;
+int Struct::static_member = -1;
+enum {
+ e3 = -1
+} conflicting_uid = e3;
+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
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Struct",
+// CHECK-SAME: scope: ![[NS]],
+// CHECK-SAME: flags: DIFlagFwdDecl,
+// CHECK-SAME: identifier: "_ZTSN8DebugCXX6StructE")
+
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "Enum",
+// CHECK-SAME: scope: ![[NS]],
+// CHECK-SAME: flags: DIFlagFwdDecl,
+// CHECK-SAME: identifier: "_ZTSN8DebugCXX4EnumE")
+
+// CHECK: !DICompositeType(tag: DW_TAG_class_type,
+
+// 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")
+
+// 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: identifier: "_ZTSN8DebugCXX8TemplateIfNS_6traitsIfEEEE")
+
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "static_member",
+// CHECK-SAME: scope: !"_ZTSN8DebugCXX6StructE"
+
+// 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)
diff --git a/test/Modules/ExtDebugInfo.m b/test/Modules/ExtDebugInfo.m
new file mode 100644
index 0000000..8e063f0
--- /dev/null
+++ b/test/Modules/ExtDebugInfo.m
@@ -0,0 +1,36 @@
+// RUN: rm -rf %t
+// Test that only forward declarations are emitted for types defined in modules.
+
+// Modules:
+// RUN: %clang_cc1 -x objective-c -debug-info-kind=limited -dwarf-ext-refs -fmodules \
+// RUN: -fmodule-format=obj -fimplicit-module-maps -DMODULES \
+// RUN: -fmodules-cache-path=%t %s -I %S/Inputs -I %t -emit-llvm -o %t-mod.ll
+// RUN: cat %t-mod.ll | FileCheck %s
+
+// PCH:
+// RUN: %clang_cc1 -x objective-c -fmodule-format=obj -emit-pch -I%S/Inputs \
+// RUN: -o %t.pch %S/Inputs/DebugObjC.h
+// RUN: %clang_cc1 -x objective-c -debug-info-kind=limited -dwarf-ext-refs -fmodule-format=obj \
+// RUN: -include-pch %t.pch %s -emit-llvm -o %t-pch.ll %s
+// RUN: cat %t-pch.ll | FileCheck %s
+
+#ifdef MODULES
+@import DebugObjC;
+#endif
+
+int foo(ObjCClass *c) {
+ InnerEnum e = e0;
+ [c instanceMethodWithInt: 0];
+ return [c property];
+}
+
+// CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ObjCClass",
+// CHECK-SAME: scope: ![[MOD:[0-9]+]],
+// 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]],
+// CHECK-SAME: flags: DIFlagFwdDecl)
diff --git a/test/Modules/Inputs/AutolinkTBD.framework/AutolinkTBD.tbd b/test/Modules/Inputs/AutolinkTBD.framework/AutolinkTBD.tbd
new file mode 100644
index 0000000..4aa0f85
--- /dev/null
+++ b/test/Modules/Inputs/AutolinkTBD.framework/AutolinkTBD.tbd
@@ -0,0 +1 @@
+empty file - clang only needs to check if it exists.
diff --git a/test/Modules/Inputs/AutolinkTBD.framework/Headers/AutolinkTBD.h b/test/Modules/Inputs/AutolinkTBD.framework/Headers/AutolinkTBD.h
new file mode 100644
index 0000000..cf790ac
--- /dev/null
+++ b/test/Modules/Inputs/AutolinkTBD.framework/Headers/AutolinkTBD.h
@@ -0,0 +1 @@
+extern int foo();
diff --git a/test/Modules/Inputs/DebugCXX.h b/test/Modules/Inputs/DebugCXX.h
new file mode 100644
index 0000000..6ef4445
--- /dev/null
+++ b/test/Modules/Inputs/DebugCXX.h
@@ -0,0 +1,52 @@
+/* -*- C++ -*- */
+namespace DebugCXX {
+ // Records.
+ struct Struct {
+ int i;
+ static int static_member;
+ };
+
+ // Enums.
+ enum Enum {
+ Enumerator
+ };
+ enum {
+ e1 = '1'
+ };
+ enum {
+ e2 = '2'
+ };
+
+ // Templates (instatiations).
+ template<typename T> struct traits {};
+ template<typename T,
+ typename Traits = traits<T>
+ > class Template {
+ T member;
+ };
+ extern template class Template<int>;
+
+ extern template struct traits<float>;
+ typedef class Template<float> FloatInstatiation;
+
+ inline void fn() {
+ Template<long> invisible;
+ }
+
+ // Non-template inside a template.
+ template <class> struct Outer {
+ Outer();
+ struct Inner {
+ Inner(Outer) {}
+ };
+ };
+ template <class T> Outer<T>::Outer() {
+ Inner a(*this);
+ };
+
+ // Partial template specialization.
+ template <typename...> class A;
+ template <typename T> class A<T> {};
+ typedef A<void> B;
+ void foo(B) {}
+}
diff --git a/test/Modules/Inputs/DebugModule.h b/test/Modules/Inputs/DebugModule.h
deleted file mode 100644
index 5612b73..0000000
--- a/test/Modules/Inputs/DebugModule.h
+++ /dev/null
@@ -1 +0,0 @@
-@class F;
diff --git a/test/Modules/Inputs/DebugObjC.h b/test/Modules/Inputs/DebugObjC.h
new file mode 100644
index 0000000..bde463a
--- /dev/null
+++ b/test/Modules/Inputs/DebugObjC.h
@@ -0,0 +1,24 @@
+@class FwdDecl;
+
+@interface ObjCClass {
+ int ivar;
+}
++ classMethod;
+- instanceMethodWithInt:(int)i;
+- (struct OpaqueData*) getSomethingOpaque;
+@property int property;
+@end
+
+@interface ObjCClass (Category)
+- categoryMethod;
+@end
+
+@protocol ObjCProtocol
+
+typedef enum {
+ e0 = 0
+} InnerEnum;
+
++ (InnerEnum)protocolMethod;
+
+@end
diff --git a/test/Modules/Inputs/DebugSubmoduleA.h b/test/Modules/Inputs/DebugSubmoduleA.h
new file mode 100644
index 0000000..1403a7d
--- /dev/null
+++ b/test/Modules/Inputs/DebugSubmoduleA.h
@@ -0,0 +1,3 @@
+struct A {
+ int a;
+};
diff --git a/test/Modules/Inputs/DebugSubmoduleB.h b/test/Modules/Inputs/DebugSubmoduleB.h
new file mode 100644
index 0000000..b06ae6a2
--- /dev/null
+++ b/test/Modules/Inputs/DebugSubmoduleB.h
@@ -0,0 +1,3 @@
+struct B {
+ int b;
+};
diff --git a/test/Modules/Inputs/ExtensionTestA.h b/test/Modules/Inputs/ExtensionTestA.h
new file mode 100644
index 0000000..fee0bb9
--- /dev/null
+++ b/test/Modules/Inputs/ExtensionTestA.h
@@ -0,0 +1 @@
+extern int ExtensionA;
diff --git a/test/Modules/Inputs/System/usr/include/assert.h b/test/Modules/Inputs/System/usr/include/assert.h
new file mode 100644
index 0000000..844e379
--- /dev/null
+++ b/test/Modules/Inputs/System/usr/include/assert.h
@@ -0,0 +1,2 @@
+// assert.h
+#define DARWIN_C_EXCLUDED 1
diff --git a/test/Modules/Inputs/System/usr/include/module.map b/test/Modules/Inputs/System/usr/include/module.map
index 9b2f3af..1d88ca3 100644
--- a/test/Modules/Inputs/System/usr/include/module.map
+++ b/test/Modules/Inputs/System/usr/include/module.map
@@ -30,3 +30,25 @@ module uses_other_constants {
header "uses_other_constants.h"
export *
}
+
+module Darwin {
+ module C {
+ module excluded {
+ requires excluded
+ header "assert.h"
+ }
+ }
+}
+
+module Tcl {
+ module Private {
+ requires excluded
+ umbrella ""
+ }
+}
+
+module IOKit {
+ module avc {
+ requires cplusplus
+ }
+}
diff --git a/test/Modules/Inputs/System/usr/include/tcl-private/header.h b/test/Modules/Inputs/System/usr/include/tcl-private/header.h
new file mode 100644
index 0000000..0e8fb64
--- /dev/null
+++ b/test/Modules/Inputs/System/usr/include/tcl-private/header.h
@@ -0,0 +1,2 @@
+// tcl-private/header.h
+#define TCL_PRIVATE 1
diff --git a/test/Modules/Inputs/auto-import-unavailable/missing_header/not_missing.h b/test/Modules/Inputs/auto-import-unavailable/missing_header/not_missing.h
new file mode 100644
index 0000000..5bab833
--- /dev/null
+++ b/test/Modules/Inputs/auto-import-unavailable/missing_header/not_missing.h
@@ -0,0 +1 @@
+// missing_header/not_missing.h
diff --git a/test/Modules/Inputs/auto-import-unavailable/missing_requirement.h b/test/Modules/Inputs/auto-import-unavailable/missing_requirement.h
new file mode 100644
index 0000000..7090978
--- /dev/null
+++ b/test/Modules/Inputs/auto-import-unavailable/missing_requirement.h
@@ -0,0 +1 @@
+// missing_requirement.h
diff --git a/test/Modules/Inputs/auto-import-unavailable/module.modulemap b/test/Modules/Inputs/auto-import-unavailable/module.modulemap
new file mode 100644
index 0000000..26196dc
--- /dev/null
+++ b/test/Modules/Inputs/auto-import-unavailable/module.modulemap
@@ -0,0 +1,19 @@
+module missing_header {
+ module missing { header "missing_header/missing.h" }
+ module error_importing_this { header "missing_header/not_missing.h" }
+}
+
+module nonrequired_missing_header {
+ module unsatisfied_requires {
+ requires nonexistent_feature
+ header "nonrequired_missing_header/missing.h"
+ }
+ module fine_to_import {
+ header "nonrequired_missing_header/not_missing.h"
+ }
+}
+
+module missing_requirement {
+ requires nonexistent_feature
+ header "missing_requirement.h"
+}
diff --git a/test/Modules/Inputs/auto-import-unavailable/nonrequired_missing_header/not_missing.h b/test/Modules/Inputs/auto-import-unavailable/nonrequired_missing_header/not_missing.h
new file mode 100644
index 0000000..3ccfcb1
--- /dev/null
+++ b/test/Modules/Inputs/auto-import-unavailable/nonrequired_missing_header/not_missing.h
@@ -0,0 +1 @@
+// nonrequired_missing_header/not_missing.h
diff --git a/test/Modules/Inputs/auto-import-unavailable/nonrequired_missing_header/requires_feature_you_dont_have.h b/test/Modules/Inputs/auto-import-unavailable/nonrequired_missing_header/requires_feature_you_dont_have.h
new file mode 100644
index 0000000..1bcb70d
--- /dev/null
+++ b/test/Modules/Inputs/auto-import-unavailable/nonrequired_missing_header/requires_feature_you_dont_have.h
@@ -0,0 +1 @@
+// nonrequired_missing_header/requires_feature_you_dont_have.h
diff --git a/test/Modules/Inputs/available-is-better/available-is-better.h b/test/Modules/Inputs/available-is-better/available-is-better.h
new file mode 100644
index 0000000..8ed0320
--- /dev/null
+++ b/test/Modules/Inputs/available-is-better/available-is-better.h
@@ -0,0 +1,2 @@
+#pragma once
+int available;
diff --git a/test/Modules/Inputs/available-is-better/module.modulemap b/test/Modules/Inputs/available-is-better/module.modulemap
new file mode 100644
index 0000000..19ffabd
--- /dev/null
+++ b/test/Modules/Inputs/available-is-better/module.modulemap
@@ -0,0 +1,17 @@
+// There is some order-dependence to how clang chooses modules, so make
+// sure that both the first and last modules here are ones that would
+// cause a test failure if they were picked.
+
+module unavailable_before {
+ requires nonexistent_feature
+ header "available-is-better.h"
+}
+
+module available {
+ header "available-is-better.h"
+}
+
+module unavailable_after {
+ requires nonexistent_feature
+ header "available-is-better.h"
+}
diff --git a/test/Modules/Inputs/builtin_sub.h b/test/Modules/Inputs/builtin_sub.h
index 79e3c03..5752ef9 100644
--- a/test/Modules/Inputs/builtin_sub.h
+++ b/test/Modules/Inputs/builtin_sub.h
@@ -2,3 +2,4 @@ int getBos1(void) {
return __builtin_object_size(p, 0);
}
+#define IS_CONST(x) __builtin_constant_p(x)
diff --git a/test/Modules/Inputs/declare-use/module.map b/test/Modules/Inputs/declare-use/module.map
index 2dad0d0..14551fd 100644
--- a/test/Modules/Inputs/declare-use/module.map
+++ b/test/Modules/Inputs/declare-use/module.map
@@ -20,14 +20,12 @@ module XD {
module XE {
header "e.h"
- header "unavailable.h"
use XA
use XB
}
module XF {
header "f.h"
- header "unavailable.h"
use XA
use XB
}
diff --git a/test/Modules/Inputs/elaborated-type-structs.h b/test/Modules/Inputs/elaborated-type-structs.h
new file mode 100644
index 0000000..da39409
--- /dev/null
+++ b/test/Modules/Inputs/elaborated-type-structs.h
@@ -0,0 +1,3 @@
+struct S1;
+struct S2 { int x; };
+struct S3 { int x; };
diff --git a/test/Modules/Inputs/explicit-build-overlap/a.h b/test/Modules/Inputs/explicit-build-overlap/a.h
new file mode 100644
index 0000000..4c5cd94
--- /dev/null
+++ b/test/Modules/Inputs/explicit-build-overlap/a.h
@@ -0,0 +1 @@
+struct A {};
diff --git a/test/Modules/Inputs/explicit-build-overlap/b.h b/test/Modules/Inputs/explicit-build-overlap/b.h
new file mode 100644
index 0000000..c51edab
--- /dev/null
+++ b/test/Modules/Inputs/explicit-build-overlap/b.h
@@ -0,0 +1 @@
+struct B {};
diff --git a/test/Modules/Inputs/explicit-build-overlap/def.map b/test/Modules/Inputs/explicit-build-overlap/def.map
new file mode 100644
index 0000000..444faf7
--- /dev/null
+++ b/test/Modules/Inputs/explicit-build-overlap/def.map
@@ -0,0 +1,2 @@
+module a { textual header "a.h" }
+module b { header "a.h" header "b.h" }
diff --git a/test/Modules/Inputs/explicit-build-overlap/use.map b/test/Modules/Inputs/explicit-build-overlap/use.map
new file mode 100644
index 0000000..456fbd0
--- /dev/null
+++ b/test/Modules/Inputs/explicit-build-overlap/use.map
@@ -0,0 +1,3 @@
+module "use" {
+ use a
+}
diff --git a/test/Modules/Inputs/internal-constants/a.h b/test/Modules/Inputs/internal-constants/a.h
new file mode 100644
index 0000000..d288138
--- /dev/null
+++ b/test/Modules/Inputs/internal-constants/a.h
@@ -0,0 +1,3 @@
+#pragma once
+#include "const.h"
+inline int f() { return N::k; }
diff --git a/test/Modules/Inputs/internal-constants/b.h b/test/Modules/Inputs/internal-constants/b.h
new file mode 100644
index 0000000..679603a
--- /dev/null
+++ b/test/Modules/Inputs/internal-constants/b.h
@@ -0,0 +1,3 @@
+#pragma once
+#include "const.h"
+inline int g() { return N::k; }
diff --git a/test/Modules/Inputs/internal-constants/c.h b/test/Modules/Inputs/internal-constants/c.h
new file mode 100644
index 0000000..43a37f8
--- /dev/null
+++ b/test/Modules/Inputs/internal-constants/c.h
@@ -0,0 +1,3 @@
+#pragma once
+#include "a.h"
+inline int h() { return N::k; }
diff --git a/test/Modules/Inputs/internal-constants/const.h b/test/Modules/Inputs/internal-constants/const.h
new file mode 100644
index 0000000..e2dc8e1
--- /dev/null
+++ b/test/Modules/Inputs/internal-constants/const.h
@@ -0,0 +1,3 @@
+namespace N {
+ const int k = 5;
+}
diff --git a/test/Modules/Inputs/internal-constants/module.modulemap b/test/Modules/Inputs/internal-constants/module.modulemap
new file mode 100644
index 0000000..6d471f5
--- /dev/null
+++ b/test/Modules/Inputs/internal-constants/module.modulemap
@@ -0,0 +1,6 @@
+module X {
+ textual header "const.h"
+ module A { header "a.h" export * }
+ module B { header "b.h" export * }
+ module C { header "c.h" export * }
+}
diff --git a/test/Modules/Inputs/libstdcxx-ambiguous-internal/a.h b/test/Modules/Inputs/libstdcxx-ambiguous-internal/a.h
new file mode 100644
index 0000000..0971369
--- /dev/null
+++ b/test/Modules/Inputs/libstdcxx-ambiguous-internal/a.h
@@ -0,0 +1,5 @@
+#ifndef A_H
+#define A_H
+static inline void f() {}
+constexpr int n = 0;
+#endif
diff --git a/test/Modules/Inputs/libstdcxx-ambiguous-internal/b.h b/test/Modules/Inputs/libstdcxx-ambiguous-internal/b.h
new file mode 100644
index 0000000..c0a8278
--- /dev/null
+++ b/test/Modules/Inputs/libstdcxx-ambiguous-internal/b.h
@@ -0,0 +1,4 @@
+#ifndef B_H
+#define B_H
+#include "a.h"
+#endif
diff --git a/test/Modules/Inputs/libstdcxx-ambiguous-internal/c.h b/test/Modules/Inputs/libstdcxx-ambiguous-internal/c.h
new file mode 100644
index 0000000..53122fa
--- /dev/null
+++ b/test/Modules/Inputs/libstdcxx-ambiguous-internal/c.h
@@ -0,0 +1,4 @@
+#ifndef C_H
+#define C_H
+#include "a.h"
+#endif
diff --git a/test/Modules/Inputs/libstdcxx-ambiguous-internal/d.h b/test/Modules/Inputs/libstdcxx-ambiguous-internal/d.h
new file mode 100644
index 0000000..efec99f
--- /dev/null
+++ b/test/Modules/Inputs/libstdcxx-ambiguous-internal/d.h
@@ -0,0 +1,4 @@
+#include "b.h"
+#include "c.h"
+inline void g() { f(); }
+inline int h() { return n; }
diff --git a/test/Modules/Inputs/libstdcxx-ambiguous-internal/module.modulemap b/test/Modules/Inputs/libstdcxx-ambiguous-internal/module.modulemap
new file mode 100644
index 0000000..12d0388
--- /dev/null
+++ b/test/Modules/Inputs/libstdcxx-ambiguous-internal/module.modulemap
@@ -0,0 +1,6 @@
+module std {
+ module A { textual header "a.h" }
+ module B { header "b.h" }
+ module C { header "c.h" }
+ module D { header "d.h" export * }
+}
diff --git a/test/Modules/Inputs/macro-reexport/module.modulemap b/test/Modules/Inputs/macro-reexport/module.modulemap
index 896bda0..f861ff8 100644
--- a/test/Modules/Inputs/macro-reexport/module.modulemap
+++ b/test/Modules/Inputs/macro-reexport/module.modulemap
@@ -19,5 +19,4 @@ module e {
}
module f {
module f1 { header "f1.h" export * }
- module f2 { header "f2.h" export * }
}
diff --git a/test/Modules/Inputs/misplaced/misplaced-a.h b/test/Modules/Inputs/misplaced/misplaced-a.h
new file mode 100644
index 0000000..f50e5ce
--- /dev/null
+++ b/test/Modules/Inputs/misplaced/misplaced-a.h
@@ -0,0 +1,5 @@
+namespace A {
+ namespace B { // expected-note{{namespace 'A::B' begins here}}
+ #include "misplaced-b.h" // expected-error{{import of module 'Misplaced.Sub_B' appears within namespace 'A::B'}}
+ }
+}
diff --git a/test/Modules/Inputs/misplaced/misplaced-b.h b/test/Modules/Inputs/misplaced/misplaced-b.h
new file mode 100644
index 0000000..68dd955
--- /dev/null
+++ b/test/Modules/Inputs/misplaced/misplaced-b.h
@@ -0,0 +1 @@
+int a; \ No newline at end of file
diff --git a/test/Modules/Inputs/misplaced/misplaced.modulemap b/test/Modules/Inputs/misplaced/misplaced.modulemap
new file mode 100644
index 0000000..50aa7a4
--- /dev/null
+++ b/test/Modules/Inputs/misplaced/misplaced.modulemap
@@ -0,0 +1,8 @@
+module Misplaced {
+ module Sub_A {
+ header "misplaced-a.h"
+ }
+ module Sub_B {
+ header "misplaced-b.h"
+ }
+}
diff --git a/test/Modules/Inputs/module-map-path-hash/a.h b/test/Modules/Inputs/module-map-path-hash/a.h
new file mode 100644
index 0000000..f137354
--- /dev/null
+++ b/test/Modules/Inputs/module-map-path-hash/a.h
@@ -0,0 +1,2 @@
+#pragma once
+int a = 42;
diff --git a/test/Modules/Inputs/module-map-path-hash/module.modulemap b/test/Modules/Inputs/module-map-path-hash/module.modulemap
new file mode 100644
index 0000000..514d745
--- /dev/null
+++ b/test/Modules/Inputs/module-map-path-hash/module.modulemap
@@ -0,0 +1,3 @@
+module a {
+ header "a.h"
+}
diff --git a/test/Modules/Inputs/module.map b/test/Modules/Inputs/module.map
index 904c65c..632517d 100644
--- a/test/Modules/Inputs/module.map
+++ b/test/Modules/Inputs/module.map
@@ -328,8 +328,12 @@ module crash {
header "crash.h"
}
-module DebugModule {
- header "DebugModule.h"
+module DebugCXX {
+ header "DebugCXX.h"
+}
+
+module DebugObjC {
+ header "DebugObjC.h"
}
module ImportNameInDir {
@@ -347,3 +351,45 @@ module RequiresWithMissingHeader {
header "RequiresWithMissingHeader-Missing2.h"
}
}
+
+module TargetFeatures {
+ module arm {
+ requires arm
+ module aarch32 { requires aarch32 }
+ module aarch64 { requires aarch64 }
+ }
+ module x86 {
+ requires x86
+ module x86_32 { requires x86_32 }
+ module x86_64 { requires x86_64 }
+ }
+}
+
+module DebugSubmodules {
+ module DebugSubmoduleA {
+ header "DebugSubmoduleA.h"
+ export *
+ }
+ module DebugSubmoduleB {
+ header "DebugSubmoduleB.h"
+ export *
+ }
+}
+
+module ExtensionTestA {
+ header "ExtensionTestA.h"
+}
+
+module TypedefTag {
+ header "typedef-tag.h"
+ explicit module Hidden {
+ header "typedef-tag-hidden.h"
+ }
+}
+
+module ElaboratedTypeStructs {
+ module Empty {}
+ module Structs {
+ header "elaborated-type-structs.h"
+ }
+}
diff --git a/test/Modules/Inputs/no-linkage/decls.h b/test/Modules/Inputs/no-linkage/decls.h
new file mode 100644
index 0000000..c8d6de5
--- /dev/null
+++ b/test/Modules/Inputs/no-linkage/decls.h
@@ -0,0 +1,11 @@
+namespace RealNS { int UsingDecl; }
+namespace NS = RealNS;
+typedef int Typedef;
+using AliasDecl = int;
+using RealNS::UsingDecl;
+struct Struct {};
+extern int Variable;
+namespace AnotherNS {}
+enum X { Enumerator };
+void Overloads();
+void Overloads(int);
diff --git a/test/Modules/Inputs/no-linkage/empty.h b/test/Modules/Inputs/no-linkage/empty.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Modules/Inputs/no-linkage/empty.h
diff --git a/test/Modules/Inputs/no-linkage/module.modulemap b/test/Modules/Inputs/no-linkage/module.modulemap
new file mode 100644
index 0000000..3931b0f
--- /dev/null
+++ b/test/Modules/Inputs/no-linkage/module.modulemap
@@ -0,0 +1 @@
+module M { module E { header "empty.h" } module D { header "decls.h" } }
diff --git a/test/Modules/Inputs/private3/private.h b/test/Modules/Inputs/private3/private.h
new file mode 100644
index 0000000..cf34b14
--- /dev/null
+++ b/test/Modules/Inputs/private3/private.h
@@ -0,0 +1,7 @@
+#ifndef PRIVATE_H
+#define PRIVATE_H
+
+void priv();
+
+#endif
+
diff --git a/test/Modules/Inputs/private3/public.h b/test/Modules/Inputs/private3/public.h
new file mode 100644
index 0000000..2cf9d21
--- /dev/null
+++ b/test/Modules/Inputs/private3/public.h
@@ -0,0 +1,11 @@
+#ifndef PUBLIC_H
+#define PUBLIC_H
+
+#include "private.h"
+
+void pub() {
+ priv();
+}
+
+#endif
+
diff --git a/test/Modules/Inputs/stress1/merge00.h b/test/Modules/Inputs/stress1/merge00.h
index 46d5e41..0aeb6ce 100644
--- a/test/Modules/Inputs/stress1/merge00.h
+++ b/test/Modules/Inputs/stress1/merge00.h
@@ -9,6 +9,10 @@
//#pragma weak pragma_weak01 // expected-warning {{weak identifier 'pragma_weak01' never declared}}
//#pragma weak pragma_weak04 // expected-warning {{weak identifier 'pragma_waek04' never declared}}
+#ifdef MERGE_NO_REEXPORT
+#include "merge_no_reexport.h"
+#endif
+
#include "common.h"
#include "m00.h"
#include "m01.h"
diff --git a/test/Modules/Inputs/stress1/merge_no_reexport.h b/test/Modules/Inputs/stress1/merge_no_reexport.h
new file mode 100644
index 0000000..7912c72
--- /dev/null
+++ b/test/Modules/Inputs/stress1/merge_no_reexport.h
@@ -0,0 +1,9 @@
+#ifndef STRESS1_MERGE_NO_REEXPORT_H
+#define STRESS1_MERGE_NO_REEXPORT_H
+
+#include "m00.h"
+#include "m01.h"
+#include "m02.h"
+#include "m03.h"
+
+#endif
diff --git a/test/Modules/Inputs/stress1/module.modulemap b/test/Modules/Inputs/stress1/module.modulemap
index 2b687b0..33eb23e 100644
--- a/test/Modules/Inputs/stress1/module.modulemap
+++ b/test/Modules/Inputs/stress1/module.modulemap
@@ -3,4 +3,5 @@ module m01 { header "Inputs/stress1/m01.h" export * }
module m02 { header "Inputs/stress1/m02.h" export * }
module m03 { header "Inputs/stress1/m03.h" export * }
+module merge_no_reexport { header "Inputs/stress1/merge_no_reexport.h" }
module merge00 { header "Inputs/stress1/merge00.h" export * }
diff --git a/test/Modules/Inputs/submodules-merge-defs/defs.h b/test/Modules/Inputs/submodules-merge-defs/defs.h
index 07dfac7..f6004f0 100644
--- a/test/Modules/Inputs/submodules-merge-defs/defs.h
+++ b/test/Modules/Inputs/submodules-merge-defs/defs.h
@@ -5,10 +5,17 @@ class B {
struct Inner1 {};
public:
struct Inner2;
+ struct Inner3;
template<typename T> void f();
};
+struct BFriend {
+ friend class B::Inner3;
+private:
+ struct Inner3Base {};
+};
// Check that lookup and access checks are performed in the right context.
struct B::Inner2 : Inner1 {};
+struct B::Inner3 : BFriend::Inner3Base {};
template<typename T> void B::f() {}
template<> inline void B::f<int>() {}
@@ -97,3 +104,37 @@ namespace MergeFunctionTemplateSpecializations {
enum ScopedEnum : int;
enum ScopedEnum : int { a, b, c };
+
+namespace RedeclDifferentDeclKind {
+ struct X {};
+ typedef X X;
+ using RedeclDifferentDeclKind::X;
+}
+
+namespace Anon {
+ struct X {
+ union {
+ int n;
+ };
+ };
+}
+
+namespace ClassTemplatePartialSpec {
+ template<typename T> struct F;
+ template<template<int> class A, int B> struct F<A<B>> {
+ template<typename C> F();
+ };
+ template<template<int> class A, int B> template<typename C> F<A<B>>::F() {}
+
+ template<typename A, int B> struct F<A[B]> {
+ template<typename C> F();
+ };
+ template<typename A, int B> template<typename C> F<A[B]>::F() {}
+}
+
+struct MemberClassTemplate {
+ template<typename T> struct A;
+};
+template<typename T> struct MemberClassTemplate::A {};
+template<typename T> struct MemberClassTemplate::A<T*> {};
+template<> struct MemberClassTemplate::A<int> {};
diff --git a/test/Modules/Inputs/template-default-args/a.h b/test/Modules/Inputs/template-default-args/a.h
index be760fe..532cbc8 100644
--- a/test/Modules/Inputs/template-default-args/a.h
+++ b/test/Modules/Inputs/template-default-args/a.h
@@ -1,3 +1,4 @@
+BEGIN
template<typename T = int> struct A {};
template<typename T> struct B {};
template<typename T> struct C;
@@ -5,3 +6,11 @@ template<typename T> struct D;
template<typename T> struct E;
template<typename T = int> struct G;
template<typename T = int> struct H;
+template<typename T> struct J {};
+template<typename T = int> struct J;
+struct K : J<> {};
+template<typename T = void> struct L;
+struct FriendL {
+ template<typename T> friend struct L;
+};
+END
diff --git a/test/Modules/Inputs/template-default-args/c.h b/test/Modules/Inputs/template-default-args/c.h
index 2946013..30cddb3 100644
--- a/test/Modules/Inputs/template-default-args/c.h
+++ b/test/Modules/Inputs/template-default-args/c.h
@@ -1,2 +1,4 @@
+BEGIN
template<typename T = int> struct F;
template<typename T, typename U> struct I;
+END
diff --git a/test/Modules/Inputs/template-default-args/d.h b/test/Modules/Inputs/template-default-args/d.h
new file mode 100644
index 0000000..5961c91
--- /dev/null
+++ b/test/Modules/Inputs/template-default-args/d.h
@@ -0,0 +1,6 @@
+BEGIN
+template<typename T = void> struct L;
+struct FriendL {
+ template<typename T> friend struct L;
+};
+END
diff --git a/test/Modules/Inputs/template-default-args/module.modulemap b/test/Modules/Inputs/template-default-args/module.modulemap
index d54dfc3..21bf40c 100644
--- a/test/Modules/Inputs/template-default-args/module.modulemap
+++ b/test/Modules/Inputs/template-default-args/module.modulemap
@@ -3,3 +3,6 @@ module X {
module B { header "b.h" }
module C { header "c.h" }
}
+module Y {
+ module D { header "d.h" }
+}
diff --git a/test/Modules/Inputs/templates-right.h b/test/Modules/Inputs/templates-right.h
index daea97b..32487c6 100644
--- a/test/Modules/Inputs/templates-right.h
+++ b/test/Modules/Inputs/templates-right.h
@@ -38,6 +38,10 @@ int defineListDoubleRight() {
return ld.size;
}
+inline void defineListLongRight() {
+ List<long> ll;
+}
+
template<typename T> struct MergePatternDecl;
void outOfLineInlineUseRightF(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::f);
diff --git a/test/Modules/Inputs/templates-top.h b/test/Modules/Inputs/templates-top.h
index 31f5e41..a082683 100644
--- a/test/Modules/Inputs/templates-top.h
+++ b/test/Modules/Inputs/templates-top.h
@@ -10,6 +10,7 @@ public:
};
extern List<double> *instantiateListDoubleDeclaration;
+extern List<long> *instantiateListLongDeclaration;
namespace A {
class Y {
diff --git a/test/Modules/Inputs/thread-safety/a.h b/test/Modules/Inputs/thread-safety/a.h
new file mode 100644
index 0000000..879c038
--- /dev/null
+++ b/test/Modules/Inputs/thread-safety/a.h
@@ -0,0 +1,4 @@
+struct __attribute__((lockable)) mutex {
+ void lock() __attribute__((exclusive_lock_function));
+ void unlock() __attribute__((unlock_function));
+};
diff --git a/test/Modules/Inputs/thread-safety/b.h b/test/Modules/Inputs/thread-safety/b.h
new file mode 100644
index 0000000..c8ed237
--- /dev/null
+++ b/test/Modules/Inputs/thread-safety/b.h
@@ -0,0 +1,8 @@
+#include "a.h"
+
+struct X {
+ mutex m;
+ int n __attribute__((guarded_by(m)));
+
+ void f();
+};
diff --git a/test/Modules/Inputs/thread-safety/c.h b/test/Modules/Inputs/thread-safety/c.h
new file mode 100644
index 0000000..ec849c2
--- /dev/null
+++ b/test/Modules/Inputs/thread-safety/c.h
@@ -0,0 +1,10 @@
+#include "a.h"
+
+struct X {
+ mutex m;
+ int n __attribute__((guarded_by(m)));
+
+ void f();
+};
+
+inline void unlock(X &x) __attribute__((unlock_function(x.m))) { x.m.unlock(); }
diff --git a/test/Modules/Inputs/thread-safety/module.map b/test/Modules/Inputs/thread-safety/module.map
new file mode 100644
index 0000000..bd6ea83
--- /dev/null
+++ b/test/Modules/Inputs/thread-safety/module.map
@@ -0,0 +1,3 @@
+module a { header "a.h" }
+module b { header "b.h" export * }
+module c { header "c.h" export * }
diff --git a/test/Modules/Inputs/typedef-tag-hidden.h b/test/Modules/Inputs/typedef-tag-hidden.h
new file mode 100644
index 0000000..eb59d69
--- /dev/null
+++ b/test/Modules/Inputs/typedef-tag-hidden.h
@@ -0,0 +1 @@
+typedef struct { int x; } TypedefStructHidden_t;
diff --git a/test/Modules/Inputs/typedef-tag.h b/test/Modules/Inputs/typedef-tag.h
new file mode 100644
index 0000000..77dff95
--- /dev/null
+++ b/test/Modules/Inputs/typedef-tag.h
@@ -0,0 +1 @@
+typedef struct { int x; } TypedefStructVisible_t;
diff --git a/test/Modules/Inputs/use-builtin.h b/test/Modules/Inputs/use-builtin.h
new file mode 100644
index 0000000..fd04741
--- /dev/null
+++ b/test/Modules/Inputs/use-builtin.h
@@ -0,0 +1,2 @@
+@import builtin;
+@import builtin.sub;
diff --git a/test/Modules/Inputs/using-decl-a.h b/test/Modules/Inputs/using-decl-a.h
index 85a4788..1d1ffe9 100644
--- a/test/Modules/Inputs/using-decl-a.h
+++ b/test/Modules/Inputs/using-decl-a.h
@@ -1,5 +1,6 @@
typedef int using_decl_type;
int using_decl_var;
+int merged;
namespace UsingDecl {
using ::using_decl_type;
diff --git a/test/Modules/Inputs/using-decl-b.h b/test/Modules/Inputs/using-decl-b.h
index b82526f..7c03d09 100644
--- a/test/Modules/Inputs/using-decl-b.h
+++ b/test/Modules/Inputs/using-decl-b.h
@@ -8,4 +8,31 @@ namespace UsingDecl {
namespace UsingDecl {
using ::using_decl_type;
using ::using_decl_var;
+ using ::merged;
}
+
+namespace X {
+ int conflicting_hidden_using_decl;
+ int conflicting_hidden_using_decl_fn();
+ int conflicting_hidden_using_decl_var;
+ struct conflicting_hidden_using_decl_struct;
+
+ int conflicting_hidden_using_decl_mixed_1;
+ int conflicting_hidden_using_decl_mixed_2();
+ struct conflicting_hidden_using_decl_mixed_3 {};
+}
+
+using X::conflicting_hidden_using_decl;
+using X::conflicting_hidden_using_decl_fn;
+using X::conflicting_hidden_using_decl_var;
+using X::conflicting_hidden_using_decl_struct;
+int conflicting_hidden_using_decl_fn_2();
+int conflicting_hidden_using_decl_var_2;
+struct conflicting_hidden_using_decl_struct_2 {};
+
+using X::conflicting_hidden_using_decl_mixed_1;
+using X::conflicting_hidden_using_decl_mixed_2;
+using X::conflicting_hidden_using_decl_mixed_3;
+int conflicting_hidden_using_decl_mixed_4;
+int conflicting_hidden_using_decl_mixed_5();
+struct conflicting_hidden_using_decl_mixed_6 {};
diff --git a/test/Modules/Inputs/using-decl-redecl/a.h b/test/Modules/Inputs/using-decl-redecl/a.h
new file mode 100644
index 0000000..4775469
--- /dev/null
+++ b/test/Modules/Inputs/using-decl-redecl/a.h
@@ -0,0 +1,2 @@
+struct string {};
+namespace N { typedef ::string clstring; }
diff --git a/test/Modules/Inputs/using-decl-redecl/b.h b/test/Modules/Inputs/using-decl-redecl/b.h
new file mode 100644
index 0000000..0714bb9
--- /dev/null
+++ b/test/Modules/Inputs/using-decl-redecl/b.h
@@ -0,0 +1,3 @@
+#include "a.h"
+namespace N { using ::N::clstring; }
+extern N::clstring b;
diff --git a/test/Modules/Inputs/using-decl-redecl/c.h b/test/Modules/Inputs/using-decl-redecl/c.h
new file mode 100644
index 0000000..e44e1a0
--- /dev/null
+++ b/test/Modules/Inputs/using-decl-redecl/c.h
@@ -0,0 +1,2 @@
+#include "b.h"
+namespace N { using ::N::clstring; }
diff --git a/test/Modules/Inputs/using-decl-redecl/module.modulemap b/test/Modules/Inputs/using-decl-redecl/module.modulemap
new file mode 100644
index 0000000..bd6ea83
--- /dev/null
+++ b/test/Modules/Inputs/using-decl-redecl/module.modulemap
@@ -0,0 +1,3 @@
+module a { header "a.h" }
+module b { header "b.h" export * }
+module c { header "c.h" export * }
diff --git a/test/Modules/Inputs/va_list/left.h b/test/Modules/Inputs/va_list/left.h
new file mode 100644
index 0000000..6842f9f
--- /dev/null
+++ b/test/Modules/Inputs/va_list/left.h
@@ -0,0 +1,7 @@
+@import top;
+
+template<typename T>
+void f(int k, ...) {
+ va_list va;
+ __builtin_va_start(va, k);
+}
diff --git a/test/Modules/Inputs/va_list/module.modulemap b/test/Modules/Inputs/va_list/module.modulemap
index 870f38b..bd9c614 100644
--- a/test/Modules/Inputs/va_list/module.modulemap
+++ b/test/Modules/Inputs/va_list/module.modulemap
@@ -1,2 +1,5 @@
module va_list_a { header "va_list_a.h" }
module va_list_b { header "va_list_b.h" }
+module top { header "top.h" }
+module left { header "left.h" }
+module right { header "right.h" }
diff --git a/test/Modules/Inputs/va_list/right.h b/test/Modules/Inputs/va_list/right.h
new file mode 100644
index 0000000..6842f9f
--- /dev/null
+++ b/test/Modules/Inputs/va_list/right.h
@@ -0,0 +1,7 @@
+@import top;
+
+template<typename T>
+void f(int k, ...) {
+ va_list va;
+ __builtin_va_start(va, k);
+}
diff --git a/test/Modules/Inputs/va_list/top.h b/test/Modules/Inputs/va_list/top.h
new file mode 100644
index 0000000..5660b87
--- /dev/null
+++ b/test/Modules/Inputs/va_list/top.h
@@ -0,0 +1 @@
+typedef __builtin_va_list va_list;
diff --git a/test/Modules/Inputs/working-dir-test/Test.framework/Headers/Test.h b/test/Modules/Inputs/working-dir-test/Test.framework/Headers/Test.h
new file mode 100644
index 0000000..ecc54bf
--- /dev/null
+++ b/test/Modules/Inputs/working-dir-test/Test.framework/Headers/Test.h
@@ -0,0 +1 @@
+void test_me_call(void);
diff --git a/test/Modules/Inputs/working-dir-test/Test.framework/Modules/module.modulemap b/test/Modules/Inputs/working-dir-test/Test.framework/Modules/module.modulemap
new file mode 100644
index 0000000..3040ac7
--- /dev/null
+++ b/test/Modules/Inputs/working-dir-test/Test.framework/Modules/module.modulemap
@@ -0,0 +1,6 @@
+framework module Test {
+ umbrella header "Test.h"
+
+ export *
+ module * { export * }
+}
diff --git a/test/Modules/ModuleDebugInfo.cpp b/test/Modules/ModuleDebugInfo.cpp
new file mode 100644
index 0000000..81192cb
--- /dev/null
+++ b/test/Modules/ModuleDebugInfo.cpp
@@ -0,0 +1,44 @@
+// Test that (the same) debug info is emitted for an Objective-C++
+// module and a C++ precompiled header.
+
+// REQUIRES: asserts, shell
+
+// Modules:
+// RUN: rm -rf %t
+// 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
+// RUN: cat %t-pch.ll | FileCheck %s
+// RUN: cat %t-mod.ll | FileCheck --check-prefix=CHECK-NEG %s
+
+#ifdef MODULES
+@import DebugCXX;
+#endif
+
+// CHECK: distinct !DICompileUnit(language: DW_LANG_{{.*}}C_plus_plus,
+// CHECK-SAME: isOptimized: false,
+// CHECK-SAME-NOT: splitDebugFilename:
+// CHECK-DWO: dwoId:
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "Enum"
+// CHECK-SAME: identifier: "_ZTSN8DebugCXX4EnumE")
+// CHECK: !DINamespace(name: "DebugCXX"
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Struct"
+// CHECK-SAME: identifier: "_ZTSN8DebugCXX6StructE")
+// CHECK: !DICompositeType(tag: DW_TAG_class_type,
+// CHECK-SAME: name: "Template<int, DebugCXX::traits<int> >"
+// CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIiNS_6traitsIiEEEE")
+// CHECK: !DICompositeType(tag: DW_TAG_class_type,
+// CHECK-SAME: name: "Template<float, DebugCXX::traits<float> >"
+// CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIfNS_6traitsIfEEEE")
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A<void>"
+// CHECK-SAME: identifier: "_ZTSN8DebugCXX1AIJvEEE")
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "FloatInstatiation"
+// no mangled name here yet.
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "B",
+// no mangled name here yet.
+
+// CHECK-NEG-NOT: "_ZTSN8DebugCXX8TemplateIlNS_6traitsIlEEEE"
diff --git a/test/Modules/ModuleDebugInfo.m b/test/Modules/ModuleDebugInfo.m
new file mode 100644
index 0000000..0974f38
--- /dev/null
+++ b/test/Modules/ModuleDebugInfo.m
@@ -0,0 +1,51 @@
+// Test that debug info is emitted for an Objective-C module and
+// a precompiled header.
+
+// REQUIRES: asserts, shell
+
+// Modules:
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x objective-c -fmodules -fmodule-format=obj \
+// RUN: -fimplicit-module-maps -DMODULES -fmodules-cache-path=%t %s \
+// 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
+
+// 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
+
+#ifdef MODULES
+@import DebugObjC;
+#endif
+
+// 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]],
+
+// The forward declaration should not be in the module scope.
+// MODULE-CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "OpaqueData", file
diff --git a/test/Modules/auto-import-unavailable.cpp b/test/Modules/auto-import-unavailable.cpp
new file mode 100644
index 0000000..a35695d
--- /dev/null
+++ b/test/Modules/auto-import-unavailable.cpp
@@ -0,0 +1,47 @@
+// RUN: rm -rf %t
+// RUN: not %clang_cc1 -x c++ -Rmodule-build -DMISSING_HEADER -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/auto-import-unavailable %s 2>&1 | FileCheck %s --check-prefix=MISSING-HEADER
+// RUN: %clang_cc1 -x c++ -Rmodule-build -DNONREQUIRED_MISSING_HEADER -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/auto-import-unavailable %s 2>&1 | FileCheck %s --check-prefix=NONREQUIRED-MISSING-HEADER
+// RUN: not %clang_cc1 -x c++ -Rmodule-build -DMISSING_REQUIREMENT -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/auto-import-unavailable %s 2>&1 | FileCheck %s --check-prefix=MISSING-REQUIREMENT
+
+#ifdef MISSING_HEADER
+
+// Even if the header we ask for is not missing, if the top-level module
+// containing it has a missing header, then the whole top-level is
+// unavailable and we issue an error.
+
+// MISSING-HEADER: module.modulemap:2:27: error: header 'missing_header/missing.h' not found
+// MISSING-HEADER-DAG: auto-import-unavailable.cpp:[[@LINE+1]]:10: note: submodule of top-level module 'missing_header' implicitly imported here
+#include "missing_header/not_missing.h"
+
+// We should not attempt to build the module.
+// MISSING-HEADER-NOT: remark: building module
+
+#endif // #ifdef MISSING_HEADER
+
+
+#ifdef NONREQUIRED_MISSING_HEADER
+
+// However, if the missing header is dominated by an unsatisfied
+// `requires`, then that is acceptable.
+// This also tests that an unsatisfied `requires` elsewhere in the
+// top-level module doesn't affect an available module.
+
+// NONREQUIRED-MISSING-HEADER: auto-import-unavailable.cpp:[[@LINE+2]]:10: remark: building module 'nonrequired_missing_header'
+// NONREQUIRED-MISSING-HEADER: auto-import-unavailable.cpp:[[@LINE+1]]:10: remark: finished building module 'nonrequired_missing_header'
+#include "nonrequired_missing_header/not_missing.h"
+
+#endif // #ifdef NONREQUIRED_MISSING_HEADER
+
+
+#ifdef MISSING_REQUIREMENT
+
+// If the header is unavailable due to a missing requirement, an error
+// should be emitted if a user tries to include it.
+
+// MISSING-REQUIREMENT:module.modulemap:16:8: error: module 'missing_requirement' requires feature 'nonexistent_feature'
+// MISSING-REQUIREMENT: auto-import-unavailable.cpp:[[@LINE+1]]:10: note: submodule of top-level module 'missing_requirement' implicitly imported here
+#include "missing_requirement.h"
+
+// MISSING-REQUIREMENT-NOT: remark: building module
+
+#endif // #ifdef MISSING_REQUIREMENT
diff --git a/test/Modules/auto-module-import.m b/test/Modules/auto-module-import.m
index de2c355..9a34c92 100644
--- a/test/Modules/auto-module-import.m
+++ b/test/Modules/auto-module-import.m
@@ -1,6 +1,7 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs %s -verify -DERRORS
// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs %s -verify
+// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -xobjective-c++ %s -verify
//
// Test both with and without the declarations that refer to unimported
// entities. For error recovery, those cases implicitly trigger an import.
@@ -83,6 +84,18 @@ int getNotInModule() {
return not_in_module;
}
-void includeNotAtTopLevel() { // expected-note {{to match this '{'}}
- #include <NoUmbrella/A.h> // expected-warning {{treating #include as an import}} expected-error {{expected '}'}}
-} // expected-error {{extraneous closing brace}}
+void includeNotAtTopLevel() { // expected-note {{function 'includeNotAtTopLevel' begins here}}
+ #include <NoUmbrella/A.h> // expected-warning {{treating #include as an import}} \
+ expected-error {{redundant #include of module 'NoUmbrella.A' appears within function 'includeNotAtTopLevel'}}
+}
+
+#ifdef __cplusplus
+namespace NS { // expected-note {{begins here}}
+#include <NoUmbrella/A.h> // expected-warning {{treating #include as an import}} \
+ expected-error {{redundant #include of module 'NoUmbrella.A' appears within namespace 'NS'}}
+}
+extern "C" { // expected-note {{begins here}}
+#include <NoUmbrella/A.h> // expected-warning {{treating #include as an import}} \
+ expected-error {{import of C++ module 'NoUmbrella.A' appears within extern "C"}}
+}
+#endif
diff --git a/test/Modules/autolinkTBD.m b/test/Modules/autolinkTBD.m
new file mode 100644
index 0000000..6107952
--- /dev/null
+++ b/test/Modules/autolinkTBD.m
@@ -0,0 +1,17 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -fno-autolink -o - -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs %s | FileCheck --check-prefix=CHECK-AUTOLINK-DISABLED %s
+
+@import AutolinkTBD;
+
+int f() {
+ return foo();
+}
+
+// CHECK: !llvm.module.flags = !{{{.*}}}
+// CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[AUTOLINK_OPTIONS:[0-9]+]]}
+// CHECK: ![[AUTOLINK_OPTIONS]] = !{![[AUTOLINK_FRAMEWORK:[0-9]+]]}
+// CHECK: ![[AUTOLINK_FRAMEWORK]] = !{!"-framework", !"AutolinkTBD"}
+
+// CHECK-AUTOLINK-DISABLED: !llvm.module.flags
+// CHECK-AUTOLINK-DISABLED-NOT: "Linker Options"
diff --git a/test/Modules/available-is-better.cpp b/test/Modules/available-is-better.cpp
new file mode 100644
index 0000000..39d37c4
--- /dev/null
+++ b/test/Modules/available-is-better.cpp
@@ -0,0 +1,5 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x c++ -Rmodule-build -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/available-is-better %s 2>&1 | FileCheck %s
+
+#include "available-is-better.h"
+// CHECK: remark: building module
diff --git a/test/Modules/builtins.m b/test/Modules/builtins.m
index c095f4f..33d2397 100644
--- a/test/Modules/builtins.m
+++ b/test/Modules/builtins.m
@@ -10,7 +10,15 @@ int bar() {
return __builtin_object_size(p, 0);
}
+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
diff --git a/test/Modules/compiler_builtins_aarch64.m b/test/Modules/compiler_builtins_aarch64.m
new file mode 100644
index 0000000..6403f09
--- /dev/null
+++ b/test/Modules/compiler_builtins_aarch64.m
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fsyntax-only -triple aarch64-unknown-unknown -target-feature +neon -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -verify %s
+// expected-no-diagnostics
+// REQUIRES: aarch64-registered-target
+@import _Builtin_intrinsics.arm;
+@import _Builtin_intrinsics.arm.neon;
diff --git a/test/Modules/cxx-irgen.cpp b/test/Modules/cxx-irgen.cpp
index 7cdb0d6..75fb2c1 100644
--- a/test/Modules/cxx-irgen.cpp
+++ b/test/Modules/cxx-irgen.cpp
@@ -1,6 +1,6 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -std=c++11 -fmodules-cache-path=%t -I %S/Inputs -triple %itanium_abi_triple -disable-llvm-optzns -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -std=c++11 -fmodules-cache-path=%t -I %S/Inputs -triple %itanium_abi_triple -disable-llvm-optzns -emit-llvm -g -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -std=c++11 -fmodules-cache-path=%t -I %S/Inputs -triple %itanium_abi_triple -disable-llvm-optzns -emit-llvm -debug-info-kind=limited -o - %s | FileCheck %s
// FIXME: When we have a syntax for modules in C++, use that.
@import cxx_irgen_top;
diff --git a/test/Modules/cxx-templates.cpp b/test/Modules/cxx-templates.cpp
index d0f5a14..ef4e4e4 100644
--- a/test/Modules/cxx-templates.cpp
+++ b/test/Modules/cxx-templates.cpp
@@ -28,8 +28,8 @@ void g() {
f<double>(1.0);
f<int>();
f(); // expected-error {{no matching function}}
- // expected-note@Inputs/cxx-templates-b.h:3 {{couldn't infer template argument}}
- // expected-note@Inputs/cxx-templates-b.h:4 {{requires single argument}}
+ // expected-note@Inputs/cxx-templates-a.h:3 {{couldn't infer template argument}}
+ // expected-note@Inputs/cxx-templates-a.h:4 {{requires 1 argument}}
N::f(0);
N::f<double>(1.0);
@@ -105,8 +105,8 @@ void g() {
TemplateInstantiationVisibility<char[1]> tiv1;
TemplateInstantiationVisibility<char[2]> tiv2;
- TemplateInstantiationVisibility<char[3]> tiv3; // expected-error {{must be imported from module 'cxx_templates_b_impl'}}
- // expected-note@cxx-templates-b-impl.h:10 {{previous definition is here}}
+ TemplateInstantiationVisibility<char[3]> tiv3; // expected-error 2{{must be imported from module 'cxx_templates_b_impl'}}
+ // expected-note@cxx-templates-b-impl.h:10 2{{previous definition is here}}
TemplateInstantiationVisibility<char[4]> tiv4;
int &p = WithPartialSpecializationUse().f();
@@ -179,18 +179,22 @@ namespace Std {
// CHECK-GLOBAL: DeclarationName 'f'
// CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f'
+// CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f'
+// CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f'
// CHECK-GLOBAL-NEXT: `-FunctionTemplate {{.*}} 'f'
// CHECK-NAMESPACE-N: DeclarationName 'f'
// CHECK-NAMESPACE-N-NEXT: |-FunctionTemplate {{.*}} 'f'
+// CHECK-NAMESPACE-N-NEXT: |-FunctionTemplate {{.*}} 'f'
+// CHECK-NAMESPACE-N-NEXT: |-FunctionTemplate {{.*}} 'f'
// CHECK-NAMESPACE-N-NEXT: `-FunctionTemplate {{.*}} 'f'
// CHECK-DUMP: ClassTemplateDecl {{.*}} <{{.*[/\\]}}cxx-templates-common.h:1:1, {{.*}}> col:{{.*}} in cxx_templates_common SomeTemplate
// CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} prev {{.*}} SomeTemplate
-// CHECK-DUMP-NEXT: TemplateArgument type 'char [2]'
-// CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} SomeTemplate definition
-// CHECK-DUMP-NEXT: TemplateArgument type 'char [2]'
-// CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} prev {{.*}} SomeTemplate
// CHECK-DUMP-NEXT: TemplateArgument type 'char [1]'
// CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} SomeTemplate definition
// CHECK-DUMP-NEXT: TemplateArgument type 'char [1]'
+// CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} prev {{.*}} SomeTemplate
+// CHECK-DUMP-NEXT: TemplateArgument type 'char [2]'
+// CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} SomeTemplate definition
+// CHECK-DUMP-NEXT: TemplateArgument type 'char [2]'
diff --git a/test/Modules/darwin_specific_modulemap_hacks.m b/test/Modules/darwin_specific_modulemap_hacks.m
new file mode 100644
index 0000000..82fc697
--- /dev/null
+++ b/test/Modules/darwin_specific_modulemap_hacks.m
@@ -0,0 +1,22 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -isystem %S/Inputs/System/usr/include -triple x86_64-apple-darwin10 %s -verify -fsyntax-only
+// expected-no-diagnostics
+
+@import Darwin.C.excluded; // no error, header is implicitly 'textual'
+@import Tcl.Private; // no error, header is implicitly 'textual'
+@import IOKit.avc; // no error, cplusplus requirement removed
+
+#if defined(DARWIN_C_EXCLUDED)
+#error assert.h should be textual
+#elif defined(TCL_PRIVATE)
+#error tcl-private/header.h should be textual
+#endif
+
+#import <assert.h>
+#import <tcl-private/header.h>
+
+#if !defined(DARWIN_C_EXCLUDED)
+#error assert.h missing
+#elif !defined(TCL_PRIVATE)
+#error tcl-private/header.h missing
+#endif
diff --git a/test/Modules/debug-info-moduleimport.m b/test/Modules/debug-info-moduleimport.m
index 1f12b02..bb0ea31 100644
--- a/test/Modules/debug-info-moduleimport.m
+++ b/test/Modules/debug-info-moduleimport.m
@@ -1,7 +1,25 @@
// RUN: rm -rf %t
-// RUN: %clang_cc1 -g -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: ![[CU:.*]] = distinct !DICompileUnit
-@import DebugModule;
-// CHECK: !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: ![[CU]], entity: ![[MODULE:.*]], line: 5)
-// CHECK: ![[MODULE]] = !DIModule(scope: null, name: "DebugModule", configMacros: "\22-DGREETING=Hello World\22 \22-UNDEBUG\22", includePath: "{{.*}}test{{.*}}Modules{{.*}}Inputs", isysroot: "/tmp/..")
+@import DebugObjC;
+// CHECK: !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: ![[CU]],
+// CHECK-SAME: entity: ![[MODULE:.*]], line: 5)
+// CHECK: ![[MODULE]] = !DIModule(scope: null, name: "DebugObjC",
+// CHECK-SAME: configMacros: "\22-DGREETING=Hello World\22 \22-UNDEBUG\22",
+// CHECK-SAME: includePath: "{{.*}}test{{.*}}Modules{{.*}}Inputs",
+// CHECK-SAME: isysroot: "/tmp/..")
+
+
+// RUN: %clang_cc1 -debug-info-kind=limited -fmodules -fimplicit-module-maps -fmodules-cache-path=%t \
+// RUN: %s -I %S/Inputs -isysroot /tmp/.. -I %t -emit-llvm -o - \
+// RUN: | FileCheck %s --check-prefix=NO-SKEL-CHECK
+// NO-SKEL-CHECK: distinct !DICompileUnit
+// NO-SKEL-CHECK-NOT: distinct !DICompileUnit
+
+// RUN: %clang_cc1 -debug-info-kind=limited -fmodules -fimplicit-module-maps -fmodules-cache-path=%t \
+// RUN: -fmodule-format=obj -dwarf-ext-refs \
+// RUN: %s -I %S/Inputs -isysroot /tmp/.. -I %t -emit-llvm -o - \
+// RUN: | FileCheck %s --check-prefix=SKEL-CHECK
+// SKEL-CHECK: distinct !DICompileUnit
+// SKEL-CHECK: distinct !DICompileUnit{{.*}}dwoId
diff --git a/test/Modules/decldef.m b/test/Modules/decldef.m
index 420c677..784743f 100644
--- a/test/Modules/decldef.m
+++ b/test/Modules/decldef.m
@@ -11,7 +11,13 @@ Def *def;
#ifdef USE_EARLY
A *a1; // expected-error{{declaration of 'A' must be imported from module 'decldef.Def' before it is required}}
#endif
-B *b1; // expected-error{{must use 'struct' tag to refer to type 'B'}}
+B *b1;
+#ifdef USE_EARLY
+// expected-error@-2{{must use 'struct' tag to refer to type 'B'}}
+#else
+// expected-error@-4{{declaration of 'B' must be imported from module 'decldef.Decl' before it is required}}
+// expected-note@Inputs/decl.h:2 {{previous}}
+#endif
@import decldef.Decl;
A *a2;
diff --git a/test/Modules/dependency-gen-pch.m b/test/Modules/dependency-gen-pch.m
index 4da054f..589865e 100644
--- a/test/Modules/dependency-gen-pch.m
+++ b/test/Modules/dependency-gen-pch.m
@@ -6,8 +6,8 @@
// RUN: FileCheck %s < %t.d
// CHECK: dependency-gen-pch.m.o
// CHECK-NEXT: dependency-gen-pch.m
+// CHECK-NEXT: Inputs{{.}}module.map
// CHECK-NEXT: diamond_top.pcm
// CHECK-NEXT: Inputs{{.}}diamond_top.h
-// CHECK-NEXT: Inputs{{.}}module.map
#import "diamond_top.h"
diff --git a/test/Modules/dependency-gen.m b/test/Modules/dependency-gen.m
index 60a7192..cb0a875 100644
--- a/test/Modules/dependency-gen.m
+++ b/test/Modules/dependency-gen.m
@@ -4,8 +4,8 @@
// RUN: %clang_cc1 -x objective-c -isystem %S/Inputs/System/usr/include -dependency-file %t.d.1 -MT %s.o -I %S/Inputs -fsyntax-only -fmodules -fimplicit-module-maps -fmodules-cache-path=%t-mcp %s
// RUN: FileCheck %s < %t.d.1
// CHECK: dependency-gen.m
-// CHECK: Inputs{{.}}diamond_top.h
// CHECK: Inputs{{.}}module.map
+// CHECK: Inputs{{.}}diamond_top.h
// CHECK-NOT: usr{{.}}include{{.}}module.map
// CHECK-NOT: stdint.h
@@ -13,8 +13,8 @@
// RUN: %clang_cc1 -x objective-c -isystem %S/Inputs/System/usr/include -dependency-file %t.d.2 -MT %s.o -I %S/Inputs -sys-header-deps -fsyntax-only -fmodules -fimplicit-module-maps -fmodules-cache-path=%t-mcp %s
// RUN: FileCheck %s -check-prefix=CHECK-SYS < %t.d.2
// CHECK-SYS: dependency-gen.m
-// CHECK-SYS: Inputs{{.}}diamond_top.h
// CHECK-SYS: Inputs{{.}}module.map
+// CHECK-SYS: Inputs{{.}}diamond_top.h
// CHECK-SYS: usr{{.}}include{{.}}module.map
// CHECK-SYS: stdint.h
diff --git a/test/Modules/dependency-gen.modulemap b/test/Modules/dependency-gen.modulemap
index a71bfe9..00a3308 100644
--- a/test/Modules/dependency-gen.modulemap
+++ b/test/Modules/dependency-gen.modulemap
@@ -1,16 +1,43 @@
// RUN: cd %S
-// RUN: rm -f %t.cpm %t-base.pcm %t-base.d %t.d
-// RUN: %clang_cc1 -I. -x c++ -fmodule-name=test-base -fmodules -emit-module -fno-validate-pch -fmodules-strict-decluse Inputs/dependency-gen-base.modulemap -dependency-file %t-base.d -MT %t-base.pcm -o %t-base.pcm -fmodule-map-file-home-is-cwd
-// RUN: %clang_cc1 -I. -x c++ -fmodule-name=test -fmodules -emit-module -fno-validate-pch -fmodules-strict-decluse -fmodule-file=%t-base.pcm %s -dependency-file %t.d -MT %t.pcm -o %t.pcm -fmodule-map-file-home-is-cwd
-// RUN: FileCheck %s < %t.d
+// RUN: rm -rf %t
+//
+// RUN: %clang_cc1 -I. -x c++ -fmodule-name=test -fmodules -emit-module -fno-validate-pch -fmodules-strict-decluse %s -dependency-file - -MT implicit.pcm -o %t/implicit.pcm -fmodules-cache-path=%t -fmodule-map-file-home-is-cwd -fmodule-map-file=%S/Inputs/dependency-gen-base.modulemap | FileCheck %s --check-prefix=IMPLICIT
+//
+// RUN: %clang_cc1 -I. -x c++ -fmodule-name=test-base -fmodules -emit-module -fno-validate-pch -fmodules-strict-decluse Inputs/dependency-gen-base.modulemap -o %t/base.pcm -fmodule-map-file-home-is-cwd -fmodule-map-file=%S/Inputs/dependency-gen-base.modulemap
+// RUN: %clang_cc1 -I. -x c++ -fmodule-name=test -fmodules -emit-module -fno-validate-pch -fmodules-strict-decluse -fmodule-file=%t/base.pcm %s -dependency-file - -MT explicit.pcm -o %t/explicit.pcm -fmodules-cache-path=%t -fmodule-map-file-home-is-cwd | FileCheck %s --check-prefix=EXPLICIT
+//
+// RUN: %clang_cc1 -I. -x c++ -fmodules -include Inputs/dependency-gen.h -x c++ /dev/null -fmodule-file=%t/explicit.pcm -MT main.o -fsyntax-only -dependency-file - | FileCheck %s --check-prefix=EXPLICIT-USE
module "test" {
export *
header "Inputs/dependency-gen.h"
use "test-base"
use "test-base2"
}
-extern module "test-base2" "Inputs/dependency-gen-base2.modulemap"
-extern module "test-base" "Inputs/dependency-gen-base.modulemap"
-// CHECK: {{ |\.[/\\]}}Inputs{{[/\\]}}dependency-gen-included2.h
-// CHECK: {{ |\.[/\\]}}Inputs{{[/\\]}}dependency-gen-base.modulemap
+// For implicit use of a module via the module cache, the input files
+// referenced by the .pcm are also dependencies of this build.
+//
+// IMPLICIT-DAG: {{[/\\]}}dependency-gen.modulemap
+// IMPLICIT-DAG: {{ |\.[/\\]}}Inputs{{[/\\]}}dependency-gen-base.modulemap
+// IMPLICIT-DAG: {{ |\.[/\\]}}Inputs{{[/\\]}}dependency-gen-base2.modulemap
+// IMPLICIT-DAG: {{ |\.[/\\]}}Inputs{{[/\\]}}dependency-gen.h
+// IMPLICIT-DAG: {{ |\.[/\\]}}Inputs{{[/\\]}}dependency-gen-included.h
+// IMPLICIT-DAG: {{ |\.[/\\]}}Inputs{{[/\\]}}dependency-gen-included2.h
+
+// For an explicit use of a module via -fmodule-file=, the other module maps
+// and included headers are not dependencies of this target (they are instead
+// dependencies of the explicitly-specified .pcm input).
+//
+// EXPLICIT: {{^}}explicit.pcm:
+// EXPLICIT-NOT: dependency-gen-
+// EXPLICIT: {{.*[/\\]}}dependency-gen.modulemap
+// EXPLICIT-NOT: dependency-gen-
+// EXPLICIT: base.pcm
+// EXPLICIT-NOT: dependency-gen-
+// EXPLICIT: {{ |\.[/\\]}}Inputs{{[/\\]}}dependency-gen.h
+// EXPLICIT-NOT: dependency-gen-
+
+// EXPLICIT-USE: main.o:
+// EXPLICIT-USE-NOT: base.pcm
+// EXPLICIT-USE: explicit.pcm
+// EXPLICIT-USE-NOT: base.pcm
diff --git a/test/Modules/elaborated-type-specifier-from-hidden-module.m b/test/Modules/elaborated-type-specifier-from-hidden-module.m
new file mode 100644
index 0000000..0ca1c24
--- /dev/null
+++ b/test/Modules/elaborated-type-specifier-from-hidden-module.m
@@ -0,0 +1,18 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs %s -verify
+
+@import ElaboratedTypeStructs.Empty; // The structs are now hidden.
+struct S1 *x;
+struct S2 *y;
+// FIXME: compatible definition should not be an error.
+struct S2 { int x; }; // expected-error {{redefinition}}
+struct S3 *z;
+// Incompatible definition.
+struct S3 { float y; }; // expected-error {{redefinition}}
+// expected-note@elaborated-type-structs.h:* 2 {{previous definition is here}}
+
+@import ElaboratedTypeStructs.Structs;
+
+void useS1(struct S1 *x);
+void useS2(struct S2 *x);
+void useS2(struct S2 *x);
diff --git a/test/Modules/embed-files.cpp b/test/Modules/embed-files.cpp
new file mode 100644
index 0000000..a1db218
--- /dev/null
+++ b/test/Modules/embed-files.cpp
@@ -0,0 +1,15 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo 'module a { header "a.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: %clang_cc1 -fmodules -I%t -fmodules-cache-path=%t -fmodule-map-file=%t/modulemap -fmodules-embed-all-files %s -verify
+#include "a.h"
+char t; // expected-error {{different type}}
+// expected-note@t.h:1 {{here}}
+#include "t.h"
+#include "b.h"
+char t; // expected-error {{different type}}
+// expected-note@t.h:1 {{here}}
diff --git a/test/Modules/empty.modulemap b/test/Modules/empty.modulemap
index 6350e2f..0d17184 100644
--- a/test/Modules/empty.modulemap
+++ b/test/Modules/empty.modulemap
@@ -10,6 +10,12 @@
// RUN: -emit-module -fmodule-name=empty -o %t/check.pcm \
// RUN: %s
//
+// The module file should be identical each time we produce it.
// RUN: diff %t/base.pcm %t/check.pcm
+//
+// We expect an empty module to be less than 30KB (and at least 10K, for now).
+// REQUIRES: shell
+// RUN: wc -c %t/base.pcm | FileCheck --check-prefix=CHECK-SIZE %s
+// CHECK-SIZE: {{(^|[^0-9])[12][0-9][0-9][0-9][0-9]($|[^0-9])}}
module empty { header "Inputs/empty.h" export * }
diff --git a/test/Modules/explicit-build-extra-files.cpp b/test/Modules/explicit-build-extra-files.cpp
new file mode 100644
index 0000000..6cec420
--- /dev/null
+++ b/test/Modules/explicit-build-extra-files.cpp
@@ -0,0 +1,14 @@
+// REQUIRES: shell
+//
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: cd %t
+// RUN: echo 'module X {}' > %t/x
+// RUN: echo 'module Y {}' > %t/y
+//
+// RUN: %clang_cc1 -emit-module -fmodules -fmodule-name=X %t/x -x c++ -o %t/x.pcm
+// RUN: %clang_cc1 -emit-module -fmodules -fmodule-name=Y %t/y -x c++ -o %t/y.pcm
+// RUN: %clang_cc1 -fmodules -fmodule-file=%t/x.pcm -fmodule-file=%t/y.pcm -x c++ /dev/null -fsyntax-only
+//
+// RUN: not test -f %t/modules.timestamp
+// RUN: not test -f %t/modules.idx
diff --git a/test/Modules/explicit-build-missing-files.cpp b/test/Modules/explicit-build-missing-files.cpp
new file mode 100644
index 0000000..1ee65d9
--- /dev/null
+++ b/test/Modules/explicit-build-missing-files.cpp
@@ -0,0 +1,56 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// 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 other {}' > %t/other.modulemap
+
+// We lazily check that the files referenced by an explicitly-specified .pcm
+// file exist. Test this by removing files and ensuring that the compilation
+// still succeeds.
+//
+// RUN: %clang_cc1 -fmodules -I %t -emit-module -fmodule-name=a -x c++ %t/modulemap -o %t/a.pcm \
+// RUN: -fmodule-map-file=%t/other.modulemap \
+// RUN: -fmodules-embed-file=%t/modulemap -fmodules-embed-file=%t/other.modulemap
+// RUN: %clang_cc1 -fmodules -I %t -emit-module -fmodule-name=a -x c++ %t/modulemap -o %t/b.pcm \
+// RUN: -fmodule-map-file=%t/other.modulemap \
+// 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: %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
+// 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: sleep 1
+// RUN: touch %t/a.h
+// 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/b.h
+// 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: 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
+
+// Oftentimes on Windows there are open handles, and deletion will fail.
+// REQUIRES: can-remove-opened-file
+
+#include "a.h" // expected-error {{file not found}}
+int x = b;
+
+#ifdef ERRORS
+int y = a2<int>;
+// CHECK: In module 'a':
+// CHECK-NEXT: a.h:1:45: error:
+
+// MISSING-B: could not find file '{{.*}}b.h'
+// MISSING-B-NOT: please delete the module cache
+#endif
+
+// RUN: not %clang_cc1 -fmodules -I %t -emit-module -fmodule-name=a -x c++ /dev/null -o %t/c.pcm \
+// RUN: -fmodules-embed-file=%t/does-not-exist 2>&1 | FileCheck %s --check-prefix=MISSING-EMBED
+// MISSING-EMBED: fatal error: file '{{.*}}does-not-exist' specified by '-fmodules-embed-file=' not found
diff --git a/test/Modules/explicit-build-overlap.cpp b/test/Modules/explicit-build-overlap.cpp
new file mode 100644
index 0000000..1966cce
--- /dev/null
+++ b/test/Modules/explicit-build-overlap.cpp
@@ -0,0 +1,14 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x c++ -fmodules %S/Inputs/explicit-build-overlap/def.map -fmodule-name=a -emit-module -o %t/a.pcm
+// RUN: %clang_cc1 -x c++ -fmodules %S/Inputs/explicit-build-overlap/def.map -fmodule-name=b -emit-module -o %t/ba.pcm -fmodule-file=%t/a.pcm
+// RUN: %clang_cc1 -x c++ -fmodules -fmodule-map-file=%S/Inputs/explicit-build-overlap/use.map -fmodule-name=use -fmodule-file=%t/ba.pcm %s -verify -I%S/Inputs/explicit-build-overlap -fmodules-decluse
+//
+// RUN: %clang_cc1 -x c++ -fmodules %S/Inputs/explicit-build-overlap/def.map -fmodule-name=b -emit-module -o %t/b.pcm
+// RUN: %clang_cc1 -x c++ -fmodules %S/Inputs/explicit-build-overlap/def.map -fmodule-name=a -emit-module -o %t/ab.pcm -fmodule-file=%t/b.pcm
+// RUN: %clang_cc1 -x c++ -fmodules -fmodule-map-file=%S/Inputs/explicit-build-overlap/use.map -fmodule-name=use -fmodule-file=%t/ab.pcm %s -verify -I%S/Inputs/explicit-build-overlap -fmodules-decluse
+
+// expected-no-diagnostics
+#include "a.h"
+
+A a;
+B b;
diff --git a/test/Modules/explicit-build.cpp b/test/Modules/explicit-build.cpp
index 01aa5dc..2a5b70d 100644
--- a/test/Modules/explicit-build.cpp
+++ b/test/Modules/explicit-build.cpp
@@ -138,7 +138,7 @@
// RUN: -fmodule-map-file=%S/Inputs/explicit-build/module.modulemap \
// RUN: %s 2>&1 | FileCheck --check-prefix=CHECK-MULTIPLE-AS %s
//
-// CHECK-MULTIPLE-AS: error: module 'a' is defined in both '{{.*}}/a{{.*}}.pcm' and '{{.*[/\\]}}a{{.*}}.pcm'
+// CHECK-MULTIPLE-AS: error: module 'a' is defined in both '{{.*[/\\]}}a{{.*}}.pcm' and '{{.*[/\\]}}a{{.*}}.pcm'
// -------------------------------
// Try to import a PCH with -fmodule-file=
@@ -179,6 +179,7 @@
// CHECK-NO-FILE-INDIRECT: error: module file '{{.*}}a.pcm' not found
// CHECK-NO-FILE-INDIRECT-NEXT: note: imported by module 'b' in '{{.*}}b.pcm'
// CHECK-NO-FILE-INDIRECT-NEXT: note: imported by module 'c' in '{{.*}}c.pcm'
+// CHECK-NO-FILE-INDIRECT-NOT: note:
// -------------------------------
// Check that we don't get upset if B's timestamp is newer than C's.
@@ -198,4 +199,6 @@
// RUN: -fmodule-file=%t/c.pcm \
// RUN: %s -DHAVE_A -DHAVE_B -DHAVE_C 2>&1 | FileCheck --check-prefix=CHECK-MISMATCHED-B %s
//
-// CHECK-MISMATCHED-B: fatal error: malformed or corrupted AST file: {{.*}}b.pcm": module file out of date
+// CHECK-MISMATCHED-B: fatal error: module file '{{.*}}b.pcm' is out of date and needs to be rebuilt
+// CHECK-MISMATCHED-B-NEXT: note: imported by module 'c'
+// CHECK-MISMATCHED-B-NOT: note:
diff --git a/test/Modules/extensions.c b/test/Modules/extensions.c
new file mode 100644
index 0000000..1858f02
--- /dev/null
+++ b/test/Modules/extensions.c
@@ -0,0 +1,44 @@
+// Test creation of modules that include extension blocks.
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -ftest-module-file-extension=clang.testA:1:5:0:user_info_for_A -ftest-module-file-extension=clang.testB:2:3:0:user_info_for_B -fmodules-cache-path=%t -I %S/Inputs %s
+
+// Make sure the extension blocks are actually there.
+// RUN: llvm-bcanalyzer %t/ExtensionTestA.pcm | FileCheck -check-prefix=CHECK-BCANALYZER %s
+// RUN: %clang_cc1 -module-file-info %t/ExtensionTestA.pcm | FileCheck -check-prefix=CHECK-INFO %s
+
+// Make sure that the readers are able to check the metadata.
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -ftest-module-file-extension=clang.testA:1:5:0:user_info_for_A -ftest-module-file-extension=clang.testB:2:3:0:user_info_for_B -fmodules-cache-path=%t -I %S/Inputs %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -ftest-module-file-extension=clang.testA:1:3:0:user_info_for_A -ftest-module-file-extension=clang.testB:3:2:0:user_info_for_B -fmodules-cache-path=%t -I %S/Inputs %s -verify
+
+// Make sure that extension blocks can be part of the module hash.
+// We test this in an obscure way, by making sure we don't get conflicts when
+// using different "versions" of the extensions. Above, the "-verify" test
+// checks that such conflicts produce errors.
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -ftest-module-file-extension=clang.testA:1:5:1:user_info_for_A -ftest-module-file-extension=clang.testB:2:3:1:user_info_for_B -fmodules-cache-path=%t -I %S/Inputs %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -ftest-module-file-extension=clang.testA:1:3:1:user_info_for_A -ftest-module-file-extension=clang.testB:3:2:1:user_info_for_B -fmodules-cache-path=%t -I %S/Inputs %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -ftest-module-file-extension=clang.testA:2:5:0:user_info_for_A -ftest-module-file-extension=clang.testB:7:3:0:user_info_for_B -fmodules-cache-path=%t -I %S/Inputs %s
+
+// Make sure we can read the message back.
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -ftest-module-file-extension=clang.testA:1:5:0:user_info_for_A -ftest-module-file-extension=clang.testB:2:3:0:user_info_for_B -fmodules-cache-path=%t -I %S/Inputs %s > %t.log 2>&1
+// RUN: FileCheck -check-prefix=CHECK-MESSAGE %s < %t.log
+
+// Make sure we diagnose duplicate module file extensions.
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -ftest-module-file-extension=clang.testA:1:5:0:user_info_for_A -ftest-module-file-extension=clang.testA:1:5:0:user_info_for_A -fmodules-cache-path=%t -I %S/Inputs %s > %t.log 2>&1
+// RUN: FileCheck -check-prefix=CHECK-DUPLICATE %s < %t.log
+
+#include "ExtensionTestA.h"
+// expected-error@-1{{test module file extension 'clang.testA' has different version (1.5) than expected (1.3)}}
+// expected-error@-2{{test module file extension 'clang.testB' has different version (2.3) than expected (3.2)}}
+
+// CHECK-BCANALYZER: {{Block ID.*EXTENSION_BLOCK}}
+// CHECK-BCANALYZER: {{100.00.*EXTENSION_METADATA}}
+
+// CHECK-INFO: Module file extension 'clang.testA' 1.5: user_info_for_A
+// CHECK-INFO: Module file extension 'clang.testB' 2.3: user_info_for_B
+
+// CHECK-MESSAGE: Read extension block message: Hello from clang.testA v1.5
+// CHECK-MESSAGE: Read extension block message: Hello from clang.testB v2.3
+
+// CHECK-DUPLICATE: warning: duplicate module file extension block name 'clang.testA'
diff --git a/test/Modules/extern_c.cpp b/test/Modules/extern_c.cpp
index f505c11..c072b7e 100644
--- a/test/Modules/extern_c.cpp
+++ b/test/Modules/extern_c.cpp
@@ -9,6 +9,8 @@
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -DCXX_HEADER -DEXTERN_CXX
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -DCXX_HEADER -DEXTERN_C -DEXTERN_CXX
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -DCXX_HEADER -DEXTERN_C -DNAMESPACE
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -DCXX_HEADER -DEXTERN_C -DNO_EXTERN_C_ERROR -Wno-module-import-in-extern-c
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -DCXX_HEADER -DEXTERN_C -DNAMESPACE -DNO_EXTERN_C_ERROR -Wno-module-import-in-extern-c
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs -x c %s
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs/elsewhere -I %S/Inputs %s -DEXTERN_C -DINDIRECT
@@ -36,12 +38,12 @@ extern "C++" {
#include HEADER
-#if defined(EXTERN_C) && !defined(EXTERN_CXX) && defined(CXX_HEADER)
-// expected-error@-3 {{import of C++ module 'cxx_library' appears within extern "C" language linkage specification}}
-// expected-note@-17 {{extern "C" language linkage specification begins here}}
-#elif defined(NAMESPACE)
-// expected-error-re@-6 {{import of module '{{c_library.inner|cxx_library}}' appears within namespace 'M'}}
-// expected-note@-24 {{namespace 'M' begins here}}
+#if defined(NAMESPACE)
+// expected-error-re@-3 {{import of module '{{c_library.inner|cxx_library}}' appears within namespace 'M'}}
+// expected-note@-21 {{namespace 'M' begins here}}
+#elif defined(EXTERN_C) && !defined(EXTERN_CXX) && defined(CXX_HEADER) && !defined(NO_EXTERN_C_ERROR)
+// expected-error@-6 {{import of C++ module 'cxx_library' appears within extern "C" language linkage specification}}
+// expected-note@-20 {{extern "C" language linkage specification begins here}}
#endif
#ifdef EXTERN_CXX
@@ -68,7 +70,7 @@ namespace N {
extern "C" {
#endif
int f;
-#if !defined(CXX_HEADER)
+#if !defined(CXX_HEADER) && !defined(NAMESPACE)
// expected-error@-2 {{redefinition of 'f' as different kind of symbol}}
// expected-note@c-header.h:1 {{previous}}
#endif
@@ -78,4 +80,6 @@ namespace N {
}
#endif
+#if !defined(NAMESPACE)
suppress_expected_no_diagnostics_error error_here; // expected-error {{}}
+#endif
diff --git a/test/Modules/fatal-module-loader-error.m b/test/Modules/fatal-module-loader-error.m
index 99a42c2..6e6131e 100644
--- a/test/Modules/fatal-module-loader-error.m
+++ b/test/Modules/fatal-module-loader-error.m
@@ -8,13 +8,13 @@
#ifdef IMPLICIT
-// expected-error@+1{{does not appear to be}}
+// expected-error@+1{{Module.pcm' is not a valid precompiled module file}}
#import <Module/Module.h>
#pragma clang __debug crash;
#else
-// expected-error@+1{{does not appear to be}}
+// expected-error@+1{{Module.pcm' is not a valid precompiled module file}}
@import Module;
#pragma clang __debug crash;
diff --git a/test/Modules/hidden-definition.cpp b/test/Modules/hidden-definition.cpp
new file mode 100644
index 0000000..d06f939
--- /dev/null
+++ b/test/Modules/hidden-definition.cpp
@@ -0,0 +1,16 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo 'struct X {}; struct Y : X { friend int f(Y); };' > %t/a.h
+// RUN: echo 'module a { header "a.h" }' > %t/map
+// RUN: %clang_cc1 -fmodules -x c++ -emit-module -fmodule-name=a %t/map -o %t/a.pcm
+// RUN: %clang_cc1 -fmodules -x c++ -verify -fmodule-file=%t/a.pcm %s -fno-modules-error-recovery
+
+struct X;
+struct Y;
+
+// Ensure that we can't use the definitions of X and Y, since we've not imported module a.
+Y *yp;
+X *xp = yp; // expected-error {{cannot initialize}}
+_Static_assert(!__is_convertible(Y*, X*), "");
+X &xr = *yp; // expected-error {{unrelated type}}
+int g(Y &y) { f(y); } // expected-error {{undeclared identifier 'f'}}
diff --git a/test/Modules/internal-constants.cpp b/test/Modules/internal-constants.cpp
new file mode 100644
index 0000000..f95e95c
--- /dev/null
+++ b/test/Modules/internal-constants.cpp
@@ -0,0 +1,12 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fmodules-local-submodule-visibility -I%S/Inputs/internal-constants %s -verify
+
+// expected-no-diagnostics
+#include "c.h"
+
+int q = h();
+int r = N::k;
+
+#include "b.h"
+
+int s = N::k; // FIXME: This should be ambiguous if we really want internal linkage declarations to not collide.
diff --git a/test/Modules/libstdcxx-ambiguous-internal.cpp b/test/Modules/libstdcxx-ambiguous-internal.cpp
new file mode 100644
index 0000000..784b442
--- /dev/null
+++ b/test/Modules/libstdcxx-ambiguous-internal.cpp
@@ -0,0 +1,13 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -emit-module -fmodule-name=std -fmodules-cache-path=%t %S/Inputs/libstdcxx-ambiguous-internal/module.modulemap -Werror
+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -emit-module -fmodule-name=std -fmodules-cache-path=%t %S/Inputs/libstdcxx-ambiguous-internal/module.modulemap -fmodules-local-submodule-visibility -DAMBIGUOUS 2>&1| FileCheck %s
+
+// CHECK-NOT: error
+// CHECK: warning: ambiguous use of internal linkage declaration 'f' defined in multiple modules
+// CHECK: note: declared here in module 'std.C'
+// CHECK: note: declared here in module 'std.B'
+// CHECK-NOT: error
+// CHECK: warning: ambiguous use of internal linkage declaration 'n' defined in multiple modules
+// CHECK: note: declared here in module 'std.C'
+// CHECK: note: declared here in module 'std.B'
+// CHECK-NOT: error
diff --git a/test/Modules/linkage-merge.cpp b/test/Modules/linkage-merge.cpp
index 005206a..dc2ad75 100644
--- a/test/Modules/linkage-merge.cpp
+++ b/test/Modules/linkage-merge.cpp
@@ -7,9 +7,5 @@ static int f(int);
int f(int);
static void g(int);
-// FIXME: Whether we notice the problem here depends on the order in which we
-// happen to find lookup results for 'g'; LookupResult::resolveKind needs to
-// be taught to prefer a visible result over a non-visible one.
-//
// expected-error@9 {{functions that differ only in their return type cannot be overloaded}}
// expected-note@Inputs/linkage-merge-foo.h:2 {{previous declaration is here}}
diff --git a/test/Modules/macros.c b/test/Modules/macros.c
index 54dca19..032eea6 100644
--- a/test/Modules/macros.c
+++ b/test/Modules/macros.c
@@ -1,8 +1,15 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -verify -fmodules-cache-path=%t -I %S/Inputs %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -verify -fmodules-cache-path=%t -I %S/Inputs %s -DALT
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -verify -fmodules-cache-path=%t -I %S/Inputs %s -detailed-preprocessing-record
-// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -DLOCAL_VISIBILITY -fmodules-local-submodule-visibility -x objective-c++ -verify -fmodules-cache-path=%t -I %S/Inputs %s
// RUN: not %clang_cc1 -E -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -I %S/Inputs %s | FileCheck -check-prefix CHECK-PREPROCESSED %s
+//
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -verify -fmodules-cache-path=%t -I %S/Inputs %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -verify -fmodules-cache-path=%t -I %S/Inputs %s -DALT
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -verify -fmodules-cache-path=%t -I %S/Inputs %s -detailed-preprocessing-record
+// RUN: not %clang_cc1 -E -fmodules -fimplicit-module-maps -x objective-c++ -fmodules-cache-path=%t -I %S/Inputs %s | FileCheck -check-prefix CHECK-PREPROCESSED %s
+//
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -DLOCAL_VISIBILITY -fmodules-local-submodule-visibility -x objective-c++ -verify -fmodules-cache-path=%t -I %S/Inputs %s
// FIXME: When we have a syntax for modules in C, use that.
// These notes come from headers in modules, and are bogus.
@@ -11,7 +18,6 @@
// expected-note@Inputs/macros_right.h:12{{expanding this definition of 'LEFT_RIGHT_DIFFERENT'}}
// expected-note@Inputs/macros_right.h:13{{expanding this definition of 'LEFT_RIGHT_DIFFERENT2'}}
// expected-note@Inputs/macros_left.h:14{{other definition of 'LEFT_RIGHT_DIFFERENT'}}
-// expected-note@Inputs/macros_left.h:11{{other definition of 'LEFT_RIGHT_DIFFERENT2'}}
@import macros;
@@ -65,9 +71,14 @@ void f() {
# error TOP should not be visible
#endif
+#undef INTEGER
+#define INTEGER int
+
// Import left module (which also imports top)
@import macros_left;
+INTEGER my_integer = 0;
+
#ifndef LEFT
# error LEFT should be visible
#endif
@@ -157,6 +168,10 @@ int TOP_DEF_RIGHT_UNDEF; // ok, no longer defined
# endif
#endif
+#ifdef ALT
+int tmp = TOP_OTHER_REDEF1;
+#endif
+
@import macros_other;
#ifndef TOP_OTHER_UNDEF1
@@ -166,13 +181,13 @@ int TOP_DEF_RIGHT_UNDEF; // ok, no longer defined
#ifndef TOP_OTHER_UNDEF2
# error TOP_OTHER_UNDEF2 should still be defined
#endif
-
+#pragma clang __debug macro TOP_OTHER_REDEF1
#ifndef TOP_OTHER_REDEF1
# error TOP_OTHER_REDEF1 should still be defined
#endif
int n1 = TOP_OTHER_REDEF1; // expected-warning{{ambiguous expansion of macro 'TOP_OTHER_REDEF1'}}
-// expected-note@macros_top.h:19 {{expanding this definition}}
-// expected-note@macros_other.h:4 {{other definition}}
+// expected-note@macros_other.h:4 {{expanding this definition}}
+// expected-note@macros_top.h:19 {{other definition}}
#ifndef TOP_OTHER_REDEF2
# error TOP_OTHER_REDEF2 should still be defined
diff --git a/test/Modules/malformed.cpp b/test/Modules/malformed.cpp
index 7d5bcc8..040361c 100644
--- a/test/Modules/malformed.cpp
+++ b/test/Modules/malformed.cpp
@@ -12,20 +12,14 @@
#include STR(HEADER)
// CHECK-A: While building module 'malformed_a'
-// CHECK-A: {{^}}Inputs/malformed/a1.h:1:{{.*}} error: expected '}'
+// CHECK-A: {{^}}Inputs/malformed/a1.h:1:{{.*}} error: expected '}' at end of module
// CHECK-A: {{^}}Inputs/malformed/a1.h:1:{{.*}} note: to match this '{'
//
// CHECK-A: While building module 'malformed_a'
// CHECK-A: {{^}}Inputs/malformed/a2.h:1:{{.*}} error: extraneous closing brace
// CHECK-B: While building module 'malformed_b'
-// CHECK-B: {{^}}Inputs/malformed/b1.h:2:{{.*}} error: expected '}'
-// CHECK-B: {{^}}Inputs/malformed/b1.h:1:{{.*}} note: to match this '{'
-// CHECK-B: {{^}}Inputs/malformed/b1.h:3:{{.*}} error: extraneous closing brace ('}')
-//
-// CHECK-B: While building module 'malformed_b'
-// CHECK-B: {{^}}Inputs/malformed/b2.h:1:{{.*}} error: redefinition of 'g'
-// CHECK-B: {{^}}Inputs/malformed/b2.h:1:{{.*}} note: previous definition is here
+// CHECK-B: {{^}}Inputs/malformed/b1.h:2:{{.*}} error: import of module 'malformed_b.b2' appears within 'S'
void test() { f<int>(); }
// Test that we use relative paths to name files within an imported module.
diff --git a/test/Modules/merge-enumerators.cpp b/test/Modules/merge-enumerators.cpp
index 34a4ec9..10e1914 100644
--- a/test/Modules/merge-enumerators.cpp
+++ b/test/Modules/merge-enumerators.cpp
@@ -4,8 +4,25 @@
// RUN: echo '#include "a.h"' > %t/b.h
// RUN: touch %t/x.h
// RUN: echo 'module B { module b { header "b.h" } module x { header "x.h" } }' > %t/b.modulemap
-// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x c++ -fmodule-map-file=%t/b.modulemap %s -I%t -verify
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x c++ -fmodule-map-file=%t/b.modulemap %s -I%t -verify -fmodules-local-submodule-visibility
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x c++ -fmodule-map-file=%t/b.modulemap %s -I%t -verify -fmodules-local-submodule-visibility -DMERGE_LATE
+
+#ifndef MERGE_LATE
// expected-no-diagnostics
#include "a.h"
+#endif
+
#include "x.h"
+
+#ifdef MERGE_LATE
+namespace N {
+ enum { A } a; // expected-note {{candidate}}
+ // expected-note@a.h:1 {{candidate}} (from module B.b)
+}
+#include "a.h"
+#endif
+
N::E e = N::A;
+#ifdef MERGE_LATE
+// expected-error@-2 {{ambiguous}}
+#endif
diff --git a/test/Modules/merge-target-features.cpp b/test/Modules/merge-target-features.cpp
index 938715d..9ca0539 100644
--- a/test/Modules/merge-target-features.cpp
+++ b/test/Modules/merge-target-features.cpp
@@ -20,7 +20,9 @@
// RUN: -target-cpu i386 \
// RUN: -fsyntax-only merge-target-features.cpp 2>&1 \
// RUN: | FileCheck --check-prefix=SUBSET %s
-// SUBSET: AST file was compiled with the target feature'+sse2' but the current translation unit is not
+// SUBSET-NOT: error:
+// SUBSET: error: {{.*}} configuration mismatch
+// SUBSET-NOT: error:
//
// RUN: %clang_cc1 -fmodules -x c++ -fmodules-cache-path=%t \
// RUN: -iquote Inputs/merge-target-features \
@@ -56,8 +58,9 @@
// RUN: -target-cpu i386 -target-feature +cx16 \
// RUN: -fsyntax-only merge-target-features.cpp 2>&1 \
// RUN: | FileCheck --check-prefix=MISMATCH %s
-// MISMATCH: AST file was compiled with the target feature'+sse2' but the current translation unit is not
-// MISMATCH: current translation unit was compiled with the target feature'+cx16' but the AST file was not
+// MISMATCH-NOT: error:
+// MISMATCH: error: {{.*}} configuration mismatch
+// MISMATCH-NOT: error:
#include "foo.h"
diff --git a/test/Modules/merge-using-decls.cpp b/test/Modules/merge-using-decls.cpp
index 789f75b..98989d1 100644
--- a/test/Modules/merge-using-decls.cpp
+++ b/test/Modules/merge-using-decls.cpp
@@ -31,6 +31,8 @@ template int UseAll<YA>();
template int UseAll<YB>();
template int UseAll<Y>();
+// Which of these two sets of diagnostics is chosen is not important. It's OK
+// if this varies with ORDER, but it must be consistent across runs.
#if ORDER == 1
// Here, we're instantiating the definition from 'A' and merging the definition
// from 'B' into it.
diff --git a/test/Modules/misplaced-1.cpp b/test/Modules/misplaced-1.cpp
new file mode 100644
index 0000000..d67ad19
--- /dev/null
+++ b/test/Modules/misplaced-1.cpp
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs %s -verify
+
+namespace N1 { // expected-note{{namespace 'N1' begins here}}
+#include "dummy.h" // expected-error{{import of module 'dummy' appears within namespace 'N1'}}
+}
diff --git a/test/Modules/misplaced-2.cpp b/test/Modules/misplaced-2.cpp
new file mode 100644
index 0000000..da46099
--- /dev/null
+++ b/test/Modules/misplaced-2.cpp
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs %s -verify
+
+void func1() { // expected-note{{function 'func1' begins here}}
+#include "dummy.h" // expected-error{{import of module 'dummy' appears within function 'func1'}}
+}
diff --git a/test/Modules/misplaced-3.cpp b/test/Modules/misplaced-3.cpp
new file mode 100644
index 0000000..6d18e13
--- /dev/null
+++ b/test/Modules/misplaced-3.cpp
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs %s -verify
+
+class C1 { // expected-note{{'C1' begins here}}
+#include "dummy.h" // expected-error{{import of module 'dummy' appears within 'C1'}}
+}
diff --git a/test/Modules/misplaced-4.cpp b/test/Modules/misplaced-4.cpp
new file mode 100644
index 0000000..8f795d5
--- /dev/null
+++ b/test/Modules/misplaced-4.cpp
@@ -0,0 +1,2 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -emit-module -fmodule-name=Misplaced -fmodules-cache-path=%t -x c++ -I %S/Inputs %S/Inputs/misplaced/misplaced.modulemap -verify
diff --git a/test/Modules/misplaced-5.c b/test/Modules/misplaced-5.c
new file mode 100644
index 0000000..ae4b3f5
--- /dev/null
+++ b/test/Modules/misplaced-5.c
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs %s -verify
+
+struct S1 { // expected-note{{'struct S1' begins here}}
+#include "dummy.h" // expected-error{{import of module 'dummy' appears within 'struct S1'}}
+}
diff --git a/test/Modules/module-map-path-hash.cpp b/test/Modules/module-map-path-hash.cpp
new file mode 100644
index 0000000..e5c9d75
--- /dev/null
+++ b/test/Modules/module-map-path-hash.cpp
@@ -0,0 +1,10 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x c++ -Rmodule-build -I%S/Inputs/module-map-path-hash -fmodules-cache-path=%t -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix=BUILD
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x c++ -Rmodule-build -I%S/Inputs//module-map-path-hash -fmodules-cache-path=%t -fsyntax-only %s 2>&1 | FileCheck -allow-empty %s --check-prefix=NOBUILD
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x c++ -Rmodule-build -I%S/Inputs/./module-map-path-hash -fmodules-cache-path=%t -fsyntax-only %s 2>&1 | FileCheck -allow-empty %s --check-prefix=NOBUILD
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x c++ -Rmodule-build -I%S/Inputs/../Inputs/module-map-path-hash -fmodules-cache-path=%t -fsyntax-only %s 2>&1 | FileCheck -allow-empty %s --check-prefix=NOBUILD
+
+#include "a.h"
+
+// BUILD: remark: building module
+// NOBUILD-NOT: remark: building module
diff --git a/test/Modules/module-private.cpp b/test/Modules/module-private.cpp
index 6e723c8..42ab185 100644
--- a/test/Modules/module-private.cpp
+++ b/test/Modules/module-private.cpp
@@ -12,11 +12,7 @@ void test() {
}
int test_broken() {
- HiddenStruct hidden; // \
- // expected-error{{must use 'struct' tag to refer to type 'HiddenStruct' in this scope}} \
- // expected-error{{definition of 'HiddenStruct' must be imported}}
- // expected-note@Inputs/module_private_left.h:3 {{previous definition is here}}
-
+ HiddenStruct hidden; // expected-error{{unknown type name 'HiddenStruct'}}
Integer i; // expected-error{{unknown type name 'Integer'}}
int *ip = 0;
diff --git a/test/Modules/modules.idx b/test/Modules/modules.idx
new file mode 100644
index 0000000..58010c0
--- /dev/null
+++ b/test/Modules/modules.idx
Binary files differ
diff --git a/test/Modules/no-implicit-builds.cpp b/test/Modules/no-implicit-builds.cpp
index bfc3562..374ed5e 100644
--- a/test/Modules/no-implicit-builds.cpp
+++ b/test/Modules/no-implicit-builds.cpp
@@ -4,6 +4,11 @@
// 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 \
// RUN: -fno-implicit-modules %s -verify
+//
+// Same thing if we're running -cc1 and no module cache path has been provided.
+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fimplicit-module-maps \
+// RUN: -fmodule-map-file=%S/Inputs/no-implicit-builds/b.modulemap \
+// RUN: %s -verify
// Compile the module and put it into the cache.
// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t \
diff --git a/test/Modules/no-linkage.cpp b/test/Modules/no-linkage.cpp
new file mode 100644
index 0000000..1ec8f40
--- /dev/null
+++ b/test/Modules/no-linkage.cpp
@@ -0,0 +1,56 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodules-local-submodule-visibility -I%S/Inputs/no-linkage -fmodule-map-file=%S/Inputs/no-linkage/module.modulemap %s -verify
+
+#include "empty.h"
+
+namespace NS { int n; } // expected-note {{candidate}}
+struct Typedef { int n; }; // expected-note {{candidate}}
+int AliasDecl; // expected-note {{candidate}}
+int UsingDecl; // expected-note {{candidate}}
+namespace RealNS = NS; // expected-note {{candidate}}
+typedef int Struct; // expected-note {{candidate}}
+enum { Variable }; // expected-note {{candidate}}
+const int AnotherNS = 0; // expected-note {{candidate}}
+const int Enumerator = 0; // expected-note {{candidate}}
+static int Overloads; // expected-note {{candidate}}
+
+// expected-note@decls.h:1 {{candidate}}
+// expected-note@decls.h:2 {{candidate}}
+// expected-note@decls.h:3 {{candidate}}
+// expected-note@decls.h:4 {{candidate}}
+// expected-note@decls.h:5 {{candidate}}
+// expected-note@decls.h:6 {{candidate}}
+// expected-note@decls.h:7 {{candidate}}
+// expected-note@decls.h:8 {{candidate}}
+// expected-note@decls.h:9 {{candidate}}
+// expected-note@decls.h:10 {{candidate}}
+// expected-note@decls.h:11 {{candidate}}
+
+void use(int);
+void use_things() {
+ use(Typedef().n);
+ use(NS::n);
+ use(AliasDecl);
+ use(UsingDecl);
+ use(RealNS::n);
+ use(Struct(0));
+ use(Variable);
+ use(AnotherNS);
+ use(Enumerator);
+ use(Overloads);
+}
+
+#include "decls.h"
+
+void use_things_again() {
+ use(Typedef().n); // expected-error {{ambiguous}}
+ use(NS::n); // expected-error {{ambiguous}}
+ use(AliasDecl); // expected-error {{ambiguous}}
+ use(UsingDecl); // expected-error {{ambiguous}}
+ use(RealNS::n); // expected-error {{ambiguous}}
+ use(Struct(0)); // expected-error {{ambiguous}}
+ use(Variable); // expected-error {{ambiguous}}
+ use(AnotherNS); // expected-error {{ambiguous}}
+ use(Enumerator); // expected-error {{ambiguous}}
+ use(Overloads); // expected-error {{ambiguous}}
+}
diff --git a/test/Modules/private.modulemap b/test/Modules/private.modulemap
new file mode 100644
index 0000000..f8b1504
--- /dev/null
+++ b/test/Modules/private.modulemap
@@ -0,0 +1,35 @@
+// RUN: rm -rf %t
+// RUN: cd %S
+// RUN: %clang_cc1 -fmodules -x c++ -std=c++11 -fmodules-cache-path=%t \
+// RUN: -I%S/Inputs/private3 -emit-module -fmodule-name=A -o %t/m.pcm %s
+// RUN: %clang_cc1 -fmodules -x c++ -std=c++11 -fmodules-cache-path=%t \
+// RUN: -I%S/Inputs/private3 -emit-module -fmodule-name=B -o %t/m.pcm %s
+// RUN: %clang_cc1 -fmodules -x c++ -std=c++11 -fmodules-cache-path=%t \
+// RUN: -I%S/Inputs/private3 -emit-module -fmodule-name=C -o %t/m.pcm %s
+// RUN: %clang_cc1 -fmodules -x c++ -std=c++11 -fmodules-cache-path=%t \
+// RUN: -I%S/Inputs/private3 -emit-module -fmodule-name=D -o %t/m.pcm %s
+
+module A {
+ header "Inputs/private3/public.h"
+ private header "Inputs/private3/private.h"
+}
+module B {
+ header "Inputs/private3/public.h"
+ module "private.h" {
+ private header "Inputs/private3/private.h"
+ }
+}
+module C {
+ module "public.h" {
+ header "Inputs/private3/public.h"
+ }
+ private header "Inputs/private3/private.h"
+}
+module D {
+ module "public.h" {
+ header "Inputs/private3/public.h"
+ }
+ module "private.h" {
+ private header "Inputs/private3/private.h"
+ }
+}
diff --git a/test/Modules/relative-dep-gen.cpp b/test/Modules/relative-dep-gen.cpp
index 86c4651..e58dd6e 100644
--- a/test/Modules/relative-dep-gen.cpp
+++ b/test/Modules/relative-dep-gen.cpp
@@ -17,8 +17,22 @@
// RUN: FileCheck --check-prefix=CHECK-BUILD %s < %t/build-cwd.d
// RUN: FileCheck --check-prefix=CHECK-USE %s < %t/use-explicit-cwd.d
// RUN: FileCheck --check-prefix=CHECK-USE %s < %t/use-implicit-cwd.d
+//
+// Check that the .d file is still correct after relocating the module.
+// RUN: mkdir %t/Inputs
+// RUN: cp %S/Inputs/relative-dep-gen-1.h %t/Inputs
+// RUN: cp %s %t
+// RUN: cd %t
+// RUN: %clang_cc1 -cc1 -fno-implicit-modules -fmodule-file=%t/mod-cwd.pcm -dependency-file %t/use-explicit-no-map-cwd.d -MT use.o relative-dep-gen.cpp -fsyntax-only -fmodule-map-file-home-is-cwd
+// RUN: cat %t/use-explicit-no-map-cwd.d
+// RUN: FileCheck --check-prefix=CHECK-USE %s < %t/use-explicit-no-map-cwd.d
#include "Inputs/relative-dep-gen-1.h"
-// CHECK-BUILD: mod.pcm: Inputs/relative-dep-gen-1.h Inputs/relative-dep-gen-2.h
-// CHECK-USE: use.o: relative-dep-gen.cpp Inputs/relative-dep-gen-1.h
+// CHECK-BUILD: mod.pcm:
+// CHECK-BUILD: {{[ \t]}}Inputs/relative-dep-gen{{(-cwd)?}}.modulemap
+// CHECK-BUILD: {{[ \t]}}Inputs/relative-dep-gen-1.h
+// CHECK-BUILD: {{[ \t]}}Inputs/relative-dep-gen-2.h
+// CHECK-USE: use.o:
+// CHECK-USE-DAG: {{[ \t]}}relative-dep-gen.cpp
+// CHECK-USE-DAG: {{[ \t]}}Inputs{{[/\\]}}relative-dep-gen-1.h
diff --git a/test/Modules/stress1.cpp b/test/Modules/stress1.cpp
index 4f3c34a..4da1edd 100644
--- a/test/Modules/stress1.cpp
+++ b/test/Modules/stress1.cpp
@@ -4,6 +4,7 @@
// RUN: %clang_cc1 -fmodules -x c++ -std=c++11 \
// RUN: -I Inputs/stress1 \
// RUN: -fno-implicit-modules \
+// RUN: -fmodules-cache-path=%t \
// RUN: -fmodule-map-file-home-is-cwd \
// RUN: -emit-module -fmodule-name=m00 -o %t/m00.pcm \
// RUN: Inputs/stress1/module.modulemap
@@ -11,6 +12,7 @@
// RUN: %clang_cc1 -fmodules -x c++ -std=c++11 \
// RUN: -I Inputs/stress1 \
// RUN: -fno-implicit-modules \
+// RUN: -fmodules-cache-path=%t \
// RUN: -fmodule-map-file-home-is-cwd \
// RUN: -emit-module -fmodule-name=m00 -o %t/m00_check.pcm \
// RUN: Inputs/stress1/module.modulemap
@@ -20,6 +22,7 @@
// RUN: %clang_cc1 -fmodules -x c++ -std=c++11 -fdelayed-template-parsing \
// RUN: -I Inputs/stress1 \
// RUN: -fno-implicit-modules \
+// RUN: -fmodules-cache-path=%t \
// RUN: -fmodule-map-file-home-is-cwd \
// RUN: -emit-module -fmodule-name=m01 -o %t/m01.pcm \
// RUN: Inputs/stress1/module.modulemap
@@ -27,6 +30,7 @@
// RUN: %clang_cc1 -fmodules -x c++ -std=c++11 -fdelayed-template-parsing \
// RUN: -I Inputs/stress1 \
// RUN: -fno-implicit-modules \
+// RUN: -fmodules-cache-path=%t \
// RUN: -fmodule-map-file-home-is-cwd \
// RUN: -emit-module -fmodule-name=m01 -o %t/m01_check.pcm \
// RUN: Inputs/stress1/module.modulemap
@@ -36,6 +40,7 @@
// RUN: %clang_cc1 -fmodules -x c++ -std=c++11 \
// RUN: -I Inputs/stress1 \
// RUN: -fno-implicit-modules \
+// RUN: -fmodules-cache-path=%t \
// RUN: -fmodule-map-file-home-is-cwd \
// RUN: -emit-module -fmodule-name=m02 -o %t/m02.pcm \
// RUN: Inputs/stress1/module.modulemap
@@ -43,6 +48,7 @@
// RUN: %clang_cc1 -fmodules -x c++ -std=c++11 \
// RUN: -I Inputs/stress1 \
// RUN: -fno-implicit-modules \
+// RUN: -fmodules-cache-path=%t \
// RUN: -fmodule-map-file-home-is-cwd \
// RUN: -emit-module -fmodule-name=m03 -o %t/m03.pcm \
// RUN: Inputs/stress1/module.modulemap
@@ -50,6 +56,7 @@
// RUN: %clang_cc1 -fmodules -x c++ -std=c++11 \
// RUN: -I Inputs/stress1 \
// RUN: -fno-implicit-modules \
+// RUN: -fmodules-cache-path=%t \
// RUN: -fmodule-map-file-home-is-cwd \
// RUN: -fmodule-file=%t/m00.pcm \
// RUN: -fmodule-file=%t/m01.pcm \
@@ -61,6 +68,7 @@
// RUN: %clang_cc1 -fmodules -x c++ -std=c++11 \
// RUN: -I Inputs/stress1 \
// RUN: -fno-implicit-modules \
+// RUN: -fmodules-cache-path=%t \
// RUN: -fmodule-map-file-home-is-cwd \
// RUN: -fmodule-file=%t/m00.pcm \
// RUN: -fmodule-file=%t/m01.pcm \
@@ -74,6 +82,7 @@
// RUN: %clang_cc1 -fmodules -x c++ -std=c++11 \
// RUN: -I Inputs/stress1 \
// RUN: -fno-implicit-modules \
+// RUN: -fmodules-cache-path=%t \
// RUN: -fmodule-map-file-home-is-cwd \
// RUN: -fmodule-map-file=Inputs/stress1/module.modulemap \
// RUN: -fmodule-file=%t/m00.pcm \
@@ -86,6 +95,7 @@
// RUN: %clang_cc1 -fmodules -x c++ -std=c++11 \
// RUN: -I Inputs/stress1 \
// RUN: -fno-implicit-modules \
+// RUN: -fmodules-cache-path=%t \
// RUN: -fmodule-map-file-home-is-cwd \
// RUN: -fmodule-map-file=Inputs/stress1/module.modulemap \
// RUN: -fmodule-file=%t/m00.pcm \
@@ -97,6 +107,18 @@
//
// RUN: diff -u %t/stress1.ll %t/stress1_check.ll
//
+// RUN: %clang_cc1 -fmodules -x c++ -std=c++11 \
+// RUN: -I Inputs/stress1 \
+// RUN: -fmodules-cache-path=%t \
+// RUN: -fmodule-map-file-home-is-cwd \
+// RUN: -fmodule-file=%t/m00.pcm \
+// RUN: -fmodule-file=%t/m01.pcm \
+// RUN: -fmodule-file=%t/m02.pcm \
+// RUN: -fmodule-file=%t/m03.pcm \
+// RUN: -emit-module -fmodule-name=merge00 -o /dev/null \
+// RUN: -DMERGE_NO_REEXPORT \
+// RUN: Inputs/stress1/module.modulemap
+//
// expected-no-diagnostics
#include "m00.h"
diff --git a/test/Modules/submodule-visibility-cycles.cpp b/test/Modules/submodule-visibility-cycles.cpp
index f26f6f2..a01fe56 100644
--- a/test/Modules/submodule-visibility-cycles.cpp
+++ b/test/Modules/submodule-visibility-cycles.cpp
@@ -3,7 +3,7 @@
#include "cycle1.h"
C1 c1;
-C2 c2; // expected-error {{must be imported}} expected-error {{}}
+C2 c2; // expected-error {{must be imported}}
// expected-note@cycle2.h:6 {{here}}
#include "cycle2.h"
diff --git a/test/Modules/submodule-visibility.cpp b/test/Modules/submodule-visibility.cpp
index b2c5fc7..345ae15 100644
--- a/test/Modules/submodule-visibility.cpp
+++ b/test/Modules/submodule-visibility.cpp
@@ -28,3 +28,10 @@ int k = n + m; // OK, a and b are visible here.
#ifndef B
#error B is not defined
#endif
+
+// Ensure we don't compute the linkage of this struct before we find it has a
+// typedef name for linkage purposes.
+typedef struct {
+ int p;
+ void (*f)(int p);
+} name_for_linkage;
diff --git a/test/Modules/submodules-merge-defs.cpp b/test/Modules/submodules-merge-defs.cpp
index 016b8a8..23d1f5c 100644
--- a/test/Modules/submodules-merge-defs.cpp
+++ b/test/Modules/submodules-merge-defs.cpp
@@ -3,7 +3,7 @@
// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/submodules-merge-defs %s -verify -fno-modules-error-recovery
// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/submodules-merge-defs %s -verify -fno-modules-error-recovery -fmodules-local-submodule-visibility -DTEXTUAL
// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/submodules-merge-defs %s -verify -fno-modules-error-recovery -fmodules-local-submodule-visibility
-// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules-cache-path=%t -fimplicit-module-maps -I %S/Inputs/submodules-merge-defs %s -verify -fno-modules-error-recovery -fmodules-local-submodule-visibility -DTEXTUAL -DEARLY_INDIRECT_INCLUDE -fno-modules-hide-internal-linkage
+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules-cache-path=%t -fimplicit-module-maps -I %S/Inputs/submodules-merge-defs %s -verify -fno-modules-error-recovery -fmodules-local-submodule-visibility -DTEXTUAL -DEARLY_INDIRECT_INCLUDE
// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/submodules-merge-defs %s -verify -fno-modules-error-recovery -fmodules-local-submodule-visibility -fmodule-feature use_defs_twice -DIMPORT_USE_2
// Trigger import of definitions, but don't make them visible.
@@ -12,7 +12,7 @@
#include "indirect.h"
#endif
-A pre_a; // expected-error {{must use 'struct'}}
+A pre_a;
#ifdef IMPORT_USE_2
// expected-error-re@-2 {{must be imported from one of {{.*}}stuff.use{{.*}}stuff.use-2}}
#elif EARLY_INDIRECT_INCLUDE
@@ -21,43 +21,42 @@ A pre_a; // expected-error {{must use 'struct'}}
// expected-error@-6 {{must be imported from module 'stuff.use'}}
#endif
// expected-note@defs.h:1 +{{here}}
+extern class A pre_a2;
+int pre_use_a = use_a(pre_a2); // expected-error 2{{'A' must be imported}} expected-error {{'use_a' must be imported}}
// expected-note@defs.h:2 +{{here}}
-int pre_use_a = use_a(pre_a); // expected-error {{'A' must be imported}} expected-error {{'use_a' must be imported}}
B::Inner2 pre_bi; // expected-error +{{must be imported}}
// expected-note@defs.h:4 +{{here}}
-// expected-note@defs.h:11 +{{here}}
-void pre_bfi(B b) { // expected-error {{must use 'class'}} expected-error +{{must be imported}}
- b.f<int>(); // expected-error +{{must be imported}} expected-error +{{}}
- // expected-note@defs.h:12 +{{here}}
+// expected-note@defs.h:17 +{{here}}
+void pre_bfi(B b) { // expected-error +{{must be imported}}
+ b.f<int>(); // expected-error +{{}}
}
C_Base<1> pre_cb1; // expected-error +{{must be imported}}
-// expected-note@defs.h:16 +{{here}}
-C1 pre_c1; // expected-error +{{must be imported}} expected-error {{must use 'struct'}}
-// expected-note@defs.h:18 +{{here}}
-C2 pre_c2; // expected-error +{{must be imported}} expected-error {{must use 'struct'}}
-// expected-note@defs.h:19 +{{here}}
+// expected-note@defs.h:23 +{{here}}
+C1 pre_c1; // expected-error +{{must be imported}}
+// expected-note@defs.h:25 +{{here}}
+C2 pre_c2; // expected-error +{{must be imported}}
+// expected-note@defs.h:26 +{{here}}
D::X pre_dx; // expected-error +{{must be imported}}
-// expected-note@defs.h:21 +{{here}}
-// expected-note@defs.h:22 +{{here}}
-// FIXME: We should warn that use_dx is being used without being imported.
-int pre_use_dx = use_dx(pre_dx);
+// expected-note@defs.h:28 +{{here}}
+// expected-note@defs.h:29 +{{here}}
+int pre_use_dx = use_dx(pre_dx); // ignored; pre_dx is invalid
int pre_e = E(0); // expected-error {{must be imported}}
-// expected-note@defs.h:25 +{{here}}
+// expected-note@defs.h:32 +{{here}}
int pre_ff = F<int>().f(); // expected-error +{{must be imported}}
-int pre_fg = F<int>().g<int>(); // expected-error +{{must be imported}}
-// expected-note@defs.h:27 +{{here}}
+int pre_fg = F<int>().g<int>(); // expected-error +{{must be imported}} expected-error 2{{expected}}
+// expected-note@defs.h:34 +{{here}}
G::A pre_ga // expected-error +{{must be imported}}
= G::a; // expected-error +{{must be imported}}
-// expected-note@defs.h:42 +{{here}}
-// expected-note@defs.h:43 +{{here}}
+// expected-note@defs.h:49 +{{here}}
+// expected-note@defs.h:50 +{{here}}
decltype(G::h) pre_gh = G::h; // expected-error +{{must be imported}}
-// expected-note@defs.h:44 +{{here}}
+// expected-note@defs.h:51 +{{here}}
J<> pre_j; // expected-error {{declaration of 'J' must be imported}}
#ifdef IMPORT_USE_2
@@ -67,10 +66,11 @@ J<> pre_j; // expected-error {{declaration of 'J' must be imported}}
#else
// expected-error@-6 {{default argument of 'J' must be imported from module 'stuff.use'}}
#endif
-// expected-note@defs.h:51 +{{here}}
+// expected-note@defs.h:58 +{{here}}
-ScopedEnum pre_scopedenum; // expected-error {{must be imported}} expected-error {{must use 'enum'}}
-// expected-note@defs.h:99 {{here}}
+ScopedEnum pre_scopedenum; // expected-error {{must be imported}}
+// expected-note@defs.h:105 0-1{{here}}
+// expected-note@defs.h:106 0-1{{here}}
enum ScopedEnum : int;
ScopedEnum pre_scopedenum_declared; // ok
@@ -104,10 +104,24 @@ template<typename T, int N, template<typename> class K> struct J;
J<> post_j2;
FriendDefArg::Y<int> friend_def_arg;
FriendDefArg::D<> friend_def_arg_d;
+int post_anon_x_n = Anon::X().n;
MergeFunctionTemplateSpecializations::X<int>::Q<char> xiqc;
#ifdef TEXTUAL
#include "use-defs.h"
void use_static_inline() { StaticInline::g({}); }
+#ifdef EARLY_INDIRECT_INCLUDE
+// expected-warning@-2 {{ambiguous use of internal linkage declaration 'g' defined in multiple modules}}
+// expected-note@defs.h:71 {{declared here in module 'redef'}}
+// expected-note@defs.h:71 {{declared here in module 'stuff.use'}}
+#endif
+int use_anon_enum = G::g;
+#ifdef EARLY_INDIRECT_INCLUDE
+// expected-warning@-2 3{{ambiguous use of internal linkage declaration 'g' defined in multiple modules}}
+// FIXME: These notes are produced, but -verify can't match them?
+// FIXME-note@defs.h:51 3{{declared here in module 'redef'}}
+// FIXME-note@defs.h:51 3{{declared here in module 'stuff.use'}}
+#endif
+int use_named_enum = G::i;
#endif
diff --git a/test/Modules/system_headers.m b/test/Modules/system_headers.m
index 165e8e8..b69ef3d 100644
--- a/test/Modules/system_headers.m
+++ b/test/Modules/system_headers.m
@@ -1,7 +1,7 @@
// Test that system-headerness works for building modules.
// RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -isystem %S/Inputs -pedantic -Werror %s -verify -std=c11
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -isystem %S/Inputs -pedantic -Werror %s -verify -std=c11
// expected-no-diagnostics
@import warning;
diff --git a/test/Modules/target-features.m b/test/Modules/target-features.m
new file mode 100644
index 0000000..b452483
--- /dev/null
+++ b/test/Modules/target-features.m
@@ -0,0 +1,61 @@
+// REQUIRES: x86-registered-target
+// REQUIRES: arm-registered-target
+// REQUIRES: aarch64-registered-target
+
+// RUN: rm -rf %t
+
+// Sanity check one of the compilations.
+// RUN: %clang_cc1 -triple aarch64-unknown-unknown -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I %S/Inputs -fsyntax-only %s -verify -DSANITY_CHECK
+// expected-no-diagnostics
+
+// Check all the targets:
+// RUN: not %clang_cc1 -triple armv7-unknown-unknown -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I %S/Inputs -fsyntax-only %s 2> %t.aarch32
+// RUN: FileCheck %s -check-prefix=AARCH32 < %t.aarch32
+// RUN: not %clang_cc1 -triple aarch64-unknown-unknown -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I %S/Inputs -fsyntax-only %s 2> %t.aarch64
+// RUN: FileCheck %s -check-prefix=AARCH64 < %t.aarch64
+// RUN: not %clang_cc1 -triple i386-unknown-unknown -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I %S/Inputs -fsyntax-only %s 2> %t.x86_32
+// RUN: FileCheck %s -check-prefix=X86_32 < %t.x86_32
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I %S/Inputs -fsyntax-only %s 2> %t.x86_64
+// RUN: FileCheck %s -check-prefix=X86_64 < %t.x86_64
+
+#ifndef SANITY_CHECK
+@import TargetFeatures;
+// AARCH32-NOT: module 'TargetFeatures' requires
+// AARCH64-NOT: module 'TargetFeatures' requires
+// X86_32-NOT: module 'TargetFeatures' requires
+// X86_64-NOT: module 'TargetFeatures' requires
+@import TargetFeatures.arm;
+// AARCH32-NOT: module 'TargetFeatures.arm' requires
+// AARCH64-NOT: module 'TargetFeatures.arm' requires
+// X86_32: module 'TargetFeatures.arm' requires feature 'arm'
+// X86_64: module 'TargetFeatures.arm' requires feature 'arm'
+@import TargetFeatures.arm.aarch32;
+// AARCH32-NOT: module 'TargetFeatures.arm.aarch32' requires
+// AARCH64: module 'TargetFeatures.arm.aarch32' requires feature 'aarch32'
+// X86_32: module 'TargetFeatures.arm.aarch32' requires feature
+// X86_64: module 'TargetFeatures.arm.aarch32' requires feature
+#endif
+
+@import TargetFeatures.arm.aarch64;
+// AARCH32: module 'TargetFeatures.arm.aarch64' requires feature 'aarch64'
+// AARCH64-NOT: module 'TargetFeatures.arm.aarch64' requires
+// X86_32: module 'TargetFeatures.arm.aarch64' requires feature
+// X86_64: module 'TargetFeatures.arm.aarch64' requires feature
+
+#ifndef SANITY_CHECK
+@import TargetFeatures.x86;
+// AARCH32: module 'TargetFeatures.x86' requires feature 'x86'
+// AARCH64: module 'TargetFeatures.x86' requires feature 'x86'
+// X86_32-NOT: module 'TargetFeatures.x86' requires
+// X86_64-NOT: module 'TargetFeatures.x86' requires
+@import TargetFeatures.x86.x86_32;
+// AARCH32: module 'TargetFeatures.x86.x86_32' requires feature
+// AARCH64: module 'TargetFeatures.x86.x86_32' requires feature
+// X86_32-NOT: module 'TargetFeatures.x86.x86_32' requires
+// X86_64: module 'TargetFeatures.x86.x86_32' requires feature 'x86_32'
+@import TargetFeatures.x86.x86_64;
+// AARCH32: module 'TargetFeatures.x86.x86_64' requires feature
+// AARCH64: module 'TargetFeatures.x86.x86_64' requires feature
+// X86_32: module 'TargetFeatures.x86.x86_64' requires feature 'x86_64'
+// X86_64-NOT: module 'TargetFeatures.x86.x86_64' requires
+#endif
diff --git a/test/Modules/template-default-args.cpp b/test/Modules/template-default-args.cpp
index dc44534..9d16cbf 100644
--- a/test/Modules/template-default-args.cpp
+++ b/test/Modules/template-default-args.cpp
@@ -1,6 +1,8 @@
// RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -fno-modules-error-recovery -I %S/Inputs/template-default-args -std=c++11 %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -fno-modules-error-recovery -I %S/Inputs/template-default-args -std=c++11 %s -DBEGIN= -DEND=
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -fno-modules-error-recovery -I %S/Inputs/template-default-args -std=c++11 %s -DBEGIN="namespace N {" -DEND="}"
+BEGIN
template<typename T> struct A;
template<typename T> struct B;
template<typename T> struct C;
@@ -8,9 +10,12 @@ template<typename T = int> struct D;
template<typename T = int> struct E {};
template<typename T> struct H {};
template<typename T = int, typename U = int> struct I {};
+END
#include "b.h"
+#include "d.h"
+BEGIN
template<typename T = int> struct A {};
template<typename T> struct B {};
template<typename T = int> struct B;
@@ -18,9 +23,14 @@ template<typename T = int> struct C;
template<typename T> struct D {};
template<typename T> struct F {};
template<typename T> struct G {};
+template<typename T> struct J {};
+template<typename T = int> struct J;
+struct K : J<> {};
+END
#include "c.h"
+BEGIN
A<> a;
B<> b;
extern C<> c;
@@ -28,7 +38,9 @@ D<> d;
E<> e;
F<> f;
G<> g; // expected-error {{default argument of 'G' must be imported from module 'X.A' before it is required}}
-// expected-note@a.h:6 {{default argument declared here}}
-H<> h; // expected-error {{default argument of 'H' must be imported from module 'X.A' before it is required}}
// expected-note@a.h:7 {{default argument declared here}}
+H<> h; // expected-error {{default argument of 'H' must be imported from module 'X.A' before it is required}}
+// expected-note@a.h:8 {{default argument declared here}}
I<> i;
+L<> *l;
+END
diff --git a/test/Modules/templates.mm b/test/Modules/templates.mm
index 4c6e472..190084a 100644
--- a/test/Modules/templates.mm
+++ b/test/Modules/templates.mm
@@ -28,6 +28,8 @@ void testTemplateClasses() {
N::Set<char> set_char;
set_char.insert('A');
+ static_assert(sizeof(List<long>) == sizeof(List<short>), "");
+
List<double> list_double;
list_double.push_back(0.0);
}
diff --git a/test/Modules/thread-safety.cpp b/test/Modules/thread-safety.cpp
new file mode 100644
index 0000000..e6e85d2
--- /dev/null
+++ b/test/Modules/thread-safety.cpp
@@ -0,0 +1,18 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps \
+// RUN: -I%S/Inputs/thread-safety -std=c++11 -Wthread-safety \
+// RUN: -verify %s
+//
+// expected-no-diagnostics
+
+#include "b.h"
+#include "c.h"
+
+bool g();
+void X::f() {
+ m.lock();
+ if (g())
+ m.unlock();
+ else
+ unlock(*this);
+}
diff --git a/test/Modules/typedef-tag-not-visible.m b/test/Modules/typedef-tag-not-visible.m
new file mode 100644
index 0000000..e1a6406
--- /dev/null
+++ b/test/Modules/typedef-tag-not-visible.m
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs %s -verify
+
+@import TypedefTag;
+
+typedef struct { int x; } TypedefStructHidden_t;
+typedef struct { int x; } TypedefStructVisible_t; // expected-error{{typedef redefinition}}
+// expected-note@typedef-tag.h:1 {{here}}
diff --git a/test/Modules/using-decl-redecl.cpp b/test/Modules/using-decl-redecl.cpp
new file mode 100644
index 0000000..0e78cec
--- /dev/null
+++ b/test/Modules/using-decl-redecl.cpp
@@ -0,0 +1,11 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t \
+// RUN: -fmodule-map-file=%S/Inputs/using-decl-redecl/module.modulemap \
+// RUN: -I%S/Inputs/using-decl-redecl \
+// RUN: -verify %s
+#include "c.h"
+N::clstring y = b;
+
+// Use a typo to trigger import of all declarations in N.
+N::clstrinh s; // expected-error {{did you mean 'clstring'}}
+// expected-note@a.h:2 {{here}}
diff --git a/test/Modules/using-decl.cpp b/test/Modules/using-decl.cpp
index a388a5b..b24593b 100644
--- a/test/Modules/using-decl.cpp
+++ b/test/Modules/using-decl.cpp
@@ -1,8 +1,84 @@
// RUN: rm -rf %t
-// RUN: %clang_cc1 -x objective-c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs %s -verify
+// RUN: %clang_cc1 -x objective-c++ -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs %s -verify -DEARLY_IMPORT
+// RUN: %clang_cc1 -x objective-c++ -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs %s -verify -UEARLY_IMPORT
+// RUN: %clang_cc1 -x objective-c++ -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs %s -verify -DEARLY_IMPORT -fmodules-local-submodule-visibility
+// RUN: %clang_cc1 -x objective-c++ -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs %s -verify -UEARLY_IMPORT -fmodules-local-submodule-visibility
+#ifdef EARLY_IMPORT
@import using_decl.a;
+namespace UsingDecl {
+ using ::merged;
+}
+int k = UsingDecl::merged;
+#endif
+
+namespace Y {
+ int conflicting_hidden_using_decl;
+ int conflicting_hidden_using_decl_fn_2();
+ int conflicting_hidden_using_decl_var_2;
+ struct conflicting_hidden_using_decl_struct_2;
+
+ struct conflicting_hidden_using_decl_mixed_4 {};
+ int conflicting_hidden_using_decl_mixed_5;
+ int conflicting_hidden_using_decl_mixed_6();
+}
+
+using Y::conflicting_hidden_using_decl;
+int conflicting_hidden_using_decl_fn();
+int conflicting_hidden_using_decl_var;
+struct conflicting_hidden_using_decl_struct {};
+using Y::conflicting_hidden_using_decl_fn_2;
+using Y::conflicting_hidden_using_decl_var_2;
+using Y::conflicting_hidden_using_decl_struct_2;
+
+struct conflicting_hidden_using_decl_mixed_1 {};
+int conflicting_hidden_using_decl_mixed_2;
+int conflicting_hidden_using_decl_mixed_3();
+using Y::conflicting_hidden_using_decl_mixed_4;
+using Y::conflicting_hidden_using_decl_mixed_5;
+using Y::conflicting_hidden_using_decl_mixed_6;
+
+template<typename T> int use(T);
+void test_conflicting() {
+ use(conflicting_hidden_using_decl);
+ use(conflicting_hidden_using_decl_fn());
+ use(conflicting_hidden_using_decl_var);
+ use(conflicting_hidden_using_decl_fn_2());
+ use(conflicting_hidden_using_decl_var_2);
+ use(conflicting_hidden_using_decl_mixed_1());
+ use(conflicting_hidden_using_decl_mixed_2);
+ use(conflicting_hidden_using_decl_mixed_3());
+ use(conflicting_hidden_using_decl_mixed_4());
+ use(conflicting_hidden_using_decl_mixed_5);
+ use(conflicting_hidden_using_decl_mixed_6());
+}
+
+#ifndef EARLY_IMPORT
+@import using_decl.a;
+#endif
-// expected-no-diagnostics
UsingDecl::using_decl_type x = UsingDecl::using_decl_var;
UsingDecl::inner y = x;
+
+@import using_decl.b;
+
+void test_conflicting_2() {
+ use(conflicting_hidden_using_decl); // expected-error {{ambiguous}}
+ use(conflicting_hidden_using_decl_fn()); // expected-error {{ambiguous}}
+ use(conflicting_hidden_using_decl_var); // expected-error {{ambiguous}}
+ use(conflicting_hidden_using_decl_fn_2()); // expected-error {{ambiguous}}
+ use(conflicting_hidden_using_decl_var_2); // expected-error {{ambiguous}}
+ use(conflicting_hidden_using_decl_mixed_1); // ok, struct hidden
+ use(conflicting_hidden_using_decl_mixed_2); // expected-error {{ambiguous}}
+ use(conflicting_hidden_using_decl_mixed_3); // ok, struct hidden
+ use(conflicting_hidden_using_decl_mixed_4); // ok, struct hidden
+ use(conflicting_hidden_using_decl_mixed_5); // expected-error {{ambiguous}}
+ use(conflicting_hidden_using_decl_mixed_6); // ok, struct hidden
+ // expected-note@using-decl.cpp:* 7{{candidate}}
+ // expected-note@using-decl-b.h:* 7{{candidate}}
+
+ int conflicting_hidden_using_decl_mixed_1::*p1;
+ int conflicting_hidden_using_decl_mixed_3::*p3;
+ int conflicting_hidden_using_decl_mixed_4::*p4;
+ int conflicting_hidden_using_decl_mixed_6::*p6;
+}
diff --git a/test/Modules/va_list.cpp b/test/Modules/va_list.cpp
new file mode 100644
index 0000000..35694cd
--- /dev/null
+++ b/test/Modules/va_list.cpp
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x objective-c++ -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/va_list %s -verify
+// expected-no-diagnostics
+
+@import left;
+@import right;
+
+void g(int k, ...) { f<int>(k); }
diff --git a/test/Modules/working-dir-flag.m b/test/Modules/working-dir-flag.m
new file mode 100644
index 0000000..0e258c0
--- /dev/null
+++ b/test/Modules/working-dir-flag.m
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t.mcp
+// RUN: %clang_cc1 -fmodules-cache-path=%t.mcp -fmodules -fimplicit-module-maps -F . -working-directory=%S/Inputs/working-dir-test %s -verify
+// expected-no-diagnostics
+
+@import Test;
+
+void foo() {
+ test_me_call();
+}
OpenPOWER on IntegriCloud