diff options
Diffstat (limited to 'test/Modules')
118 files changed, 1079 insertions, 36 deletions
diff --git a/test/Modules/Inputs/DependsOnModule.framework/Headers/not_cxx.h b/test/Modules/Inputs/DependsOnModule.framework/Headers/not_cxx.h new file mode 100644 index 0000000..c29a921 --- /dev/null +++ b/test/Modules/Inputs/DependsOnModule.framework/Headers/not_cxx.h @@ -0,0 +1 @@ +extern int template; diff --git a/test/Modules/Inputs/DependsOnModule.framework/Headers/not_objc.h b/test/Modules/Inputs/DependsOnModule.framework/Headers/not_objc.h new file mode 100644 index 0000000..f63975a --- /dev/null +++ b/test/Modules/Inputs/DependsOnModule.framework/Headers/not_objc.h @@ -0,0 +1 @@ +int NSObject; diff --git a/test/Modules/Inputs/DependsOnModule.framework/module.map b/test/Modules/Inputs/DependsOnModule.framework/module.map index 2a3dd80..5a1caca 100644 --- a/test/Modules/Inputs/DependsOnModule.framework/module.map +++ b/test/Modules/Inputs/DependsOnModule.framework/module.map @@ -8,6 +8,14 @@ framework module DependsOnModule { requires cplusplus header "cxx_other.h" } + explicit module NotCXX { + requires !cplusplus + header "not_cxx.h" + } + explicit module NotObjC { + requires !objc + header "not_objc.h" + } explicit framework module SubFramework { umbrella header "SubFramework.h" diff --git a/test/Modules/Inputs/MethodPoolBSub.h b/test/Modules/Inputs/MethodPoolBSub.h index 0a7899d..fbfc0aa 100644 --- a/test/Modules/Inputs/MethodPoolBSub.h +++ b/test/Modules/Inputs/MethodPoolBSub.h @@ -1,4 +1,5 @@ @interface B (Sub) - (char *)method3; - (char*)method4; +- (id)method6; @end diff --git a/test/Modules/Inputs/MethodPoolBSub2.h b/test/Modules/Inputs/MethodPoolBSub2.h new file mode 100644 index 0000000..8bc369f --- /dev/null +++ b/test/Modules/Inputs/MethodPoolBSub2.h @@ -0,0 +1,3 @@ +@interface TotallyUnrelated +- (id)method6; +@end diff --git a/test/Modules/Inputs/System/usr/include/stdio.h b/test/Modules/Inputs/System/usr/include/stdio.h index 9a7b106..f41e09c 100644 --- a/test/Modules/Inputs/System/usr/include/stdio.h +++ b/test/Modules/Inputs/System/usr/include/stdio.h @@ -1,3 +1,3 @@ typedef struct { int id; } FILE; int fprintf(FILE*restrict, const char* restrict format, ...); - +extern FILE *__stderrp; diff --git a/test/Modules/Inputs/cxx-decls-imported.h b/test/Modules/Inputs/cxx-decls-imported.h new file mode 100644 index 0000000..b943686 --- /dev/null +++ b/test/Modules/Inputs/cxx-decls-imported.h @@ -0,0 +1,5 @@ +class HasFriends { + friend void friend_1(HasFriends); + friend void friend_2(HasFriends); + void private_thing(); +}; diff --git a/test/Modules/Inputs/cxx-decls-unimported.h b/test/Modules/Inputs/cxx-decls-unimported.h new file mode 100644 index 0000000..0431e32 --- /dev/null +++ b/test/Modules/Inputs/cxx-decls-unimported.h @@ -0,0 +1 @@ +void operator delete(void*); diff --git a/test/Modules/Inputs/cxx-templates-a.h b/test/Modules/Inputs/cxx-templates-a.h new file mode 100644 index 0000000..0b1614d --- /dev/null +++ b/test/Modules/Inputs/cxx-templates-a.h @@ -0,0 +1,50 @@ +@import cxx_templates_common; + +template<typename T> T f() { return T(); } +template<typename T> T f(T); +namespace N { + template<typename T> T f() { return T(); } + template<typename T> T f(T); +} + +template<int N> int template_param_kinds_1(); +template<template<typename T, int, int> class> int template_param_kinds_2(); +template<template<typename T, typename U, T> class> int template_param_kinds_3(); + +template<typename T> struct SomeTemplate<T*>; +template<typename T> struct SomeTemplate<T*> {}; +typedef SomeTemplate<int*> SomeTemplateIntPtr; + +template<typename T> void PerformDelayedLookup(T &t) { + t.f(); + typename T::Inner inner; + FoundByADL(t); +} + +template<typename T> void PerformDelayedLookupInDefaultArgument(T &t, int a = (FoundByADL(T()), 0)) {} + +template<typename T> struct RedeclaredAsFriend {}; + +void use_some_template_a() { + SomeTemplate<char[2]> a; + SomeTemplate<char[1]> b, c; + b = c; +} + +template<int> struct MergeTemplates; +MergeTemplates<0> *merge_templates_a; + +auto enum_a_from_a = CommonTemplate<int>::a; +const auto enum_c_from_a = CommonTemplate<int>::c; + +template<int> struct UseInt; +template<typename T> void UseRedeclaredEnum(UseInt<T() + CommonTemplate<char>::a>); +constexpr void (*UseRedeclaredEnumA)(UseInt<1>) = UseRedeclaredEnum<int>; + +template<typename> struct MergeSpecializations; +template<typename T> struct MergeSpecializations<T*> { + typedef int partially_specialized_in_a; +}; +template<> struct MergeSpecializations<char> { + typedef int explicitly_specialized_in_a; +}; diff --git a/test/Modules/Inputs/cxx-templates-b-impl.h b/test/Modules/Inputs/cxx-templates-b-impl.h new file mode 100644 index 0000000..fdf4a4f --- /dev/null +++ b/test/Modules/Inputs/cxx-templates-b-impl.h @@ -0,0 +1,5 @@ +struct DefinedInBImpl { + void f(); + struct Inner {}; + friend void FoundByADL(DefinedInBImpl); +}; diff --git a/test/Modules/Inputs/cxx-templates-b.h b/test/Modules/Inputs/cxx-templates-b.h new file mode 100644 index 0000000..6cd83fa --- /dev/null +++ b/test/Modules/Inputs/cxx-templates-b.h @@ -0,0 +1,69 @@ +@import cxx_templates_common; + +template<typename T> T f(); +template<typename T> T f(T t) { return t; } +namespace N { + template<typename T> T f(); + template<typename T> T f(T t) { return t; } +} + +template<typename> int template_param_kinds_1(); +template<template<typename, int, int...> class> int template_param_kinds_2(); +template<template<typename T, typename U, U> class> int template_param_kinds_3(); + +template<typename T> struct SomeTemplate<T&> {}; +template<typename T> struct SomeTemplate<T&>; +typedef SomeTemplate<int&> SomeTemplateIntRef; + +extern DefinedInCommon &defined_in_common; + +template<int> struct MergeTemplates; +MergeTemplates<0> *merge_templates_b; + +@import cxx_templates_b_impl; + +template<typename T, typename> struct Identity { typedef T type; }; +template<typename T> void UseDefinedInBImpl() { + typename Identity<DefinedInBImpl, T>::type dependent; + FoundByADL(dependent); + typename Identity<DefinedInBImpl, T>::type::Inner inner; + dependent.f(); +} + +extern DefinedInBImpl &defined_in_b_impl; + +template<typename T> +struct RedeclareTemplateAsFriend { + template<typename U> + friend struct RedeclaredAsFriend; +}; + +void use_some_template_b() { + SomeTemplate<char[1]> a; + SomeTemplate<char[2]> b, c; + b = c; +} + +auto enum_b_from_b = CommonTemplate<int>::b; +const auto enum_c_from_b = CommonTemplate<int>::c; + +template<int> struct UseInt; +template<typename T> void UseRedeclaredEnum(UseInt<T() + CommonTemplate<char>::a>); +constexpr void (*UseRedeclaredEnumB)(UseInt<1>) = UseRedeclaredEnum<int>; + +template<typename> struct MergeSpecializations; +template<typename T> struct MergeSpecializations<T&> { + typedef int partially_specialized_in_b; +}; +template<> struct MergeSpecializations<double> { + typedef int explicitly_specialized_in_b; +}; + +@import cxx_templates_a; +template<typename T> void UseDefinedInBImplIndirectly(T &v) { + PerformDelayedLookup(v); +} + +void TriggerInstantiation() { + UseDefinedInBImpl<void>(); +} diff --git a/test/Modules/Inputs/cxx-templates-c.h b/test/Modules/Inputs/cxx-templates-c.h new file mode 100644 index 0000000..4c0fc8a --- /dev/null +++ b/test/Modules/Inputs/cxx-templates-c.h @@ -0,0 +1,7 @@ +template<typename> struct MergeSpecializations; +template<typename T> struct MergeSpecializations<T[]> { + typedef int partially_specialized_in_c; +}; +template<> struct MergeSpecializations<bool> { + typedef int explicitly_specialized_in_c; +}; diff --git a/test/Modules/Inputs/cxx-templates-common.h b/test/Modules/Inputs/cxx-templates-common.h new file mode 100644 index 0000000..40a11e2 --- /dev/null +++ b/test/Modules/Inputs/cxx-templates-common.h @@ -0,0 +1,11 @@ +template<typename T> struct SomeTemplate {}; + +struct DefinedInCommon { + void f(); + struct Inner {}; + friend void FoundByADL(DefinedInCommon); +}; + +template<typename T> struct CommonTemplate { + enum E { a = 1, b = 2, c = 3 }; +}; diff --git a/test/Modules/Inputs/declare-use/a.h b/test/Modules/Inputs/declare-use/a.h new file mode 100644 index 0000000..a36dc1b --- /dev/null +++ b/test/Modules/Inputs/declare-use/a.h @@ -0,0 +1,4 @@ +#ifndef A_H +#define A_H +const int a = 2; +#endif diff --git a/test/Modules/Inputs/declare-use/b.h b/test/Modules/Inputs/declare-use/b.h new file mode 100644 index 0000000..55daf72 --- /dev/null +++ b/test/Modules/Inputs/declare-use/b.h @@ -0,0 +1,4 @@ +#ifndef B_H +#define B_H +const int b = 3; +#endif diff --git a/test/Modules/Inputs/declare-use/c.h b/test/Modules/Inputs/declare-use/c.h new file mode 100644 index 0000000..a24cd5a --- /dev/null +++ b/test/Modules/Inputs/declare-use/c.h @@ -0,0 +1,6 @@ +#ifndef C_H +#define C_H +#include "a.h" +#include "b.h" +const int c = a+b; +#endif diff --git a/test/Modules/Inputs/declare-use/d.h b/test/Modules/Inputs/declare-use/d.h new file mode 100644 index 0000000..a597b01 --- /dev/null +++ b/test/Modules/Inputs/declare-use/d.h @@ -0,0 +1,6 @@ +#ifndef D_H +#define D_H +#include "a.h" +#include "b.h" +const int d = a+b; +#endif diff --git a/test/Modules/Inputs/declare-use/e.h b/test/Modules/Inputs/declare-use/e.h new file mode 100644 index 0000000..ed8d843 --- /dev/null +++ b/test/Modules/Inputs/declare-use/e.h @@ -0,0 +1,6 @@ +#ifndef E_H +#define E_H +#include "a.h" +#include "b.h" +const int e = a*b; +#endif diff --git a/test/Modules/Inputs/declare-use/f.h b/test/Modules/Inputs/declare-use/f.h new file mode 100644 index 0000000..1d8e2fd --- /dev/null +++ b/test/Modules/Inputs/declare-use/f.h @@ -0,0 +1,6 @@ +#ifndef F_H +#define F_H +#include "a.h" +#include "b.h" +const int f = a+b; +#endif diff --git a/test/Modules/Inputs/declare-use/g.h b/test/Modules/Inputs/declare-use/g.h new file mode 100644 index 0000000..2a59017 --- /dev/null +++ b/test/Modules/Inputs/declare-use/g.h @@ -0,0 +1,6 @@ +#ifndef G_H +#define G_H +#include "c.h" +#include "g1.h" +const int g1 = aux_g*c*7; +#endif diff --git a/test/Modules/Inputs/declare-use/g1.h b/test/Modules/Inputs/declare-use/g1.h new file mode 100644 index 0000000..78a0724 --- /dev/null +++ b/test/Modules/Inputs/declare-use/g1.h @@ -0,0 +1 @@ +int aux_g = 11; diff --git a/test/Modules/Inputs/declare-use/h.h b/test/Modules/Inputs/declare-use/h.h new file mode 100644 index 0000000..df99a6d --- /dev/null +++ b/test/Modules/Inputs/declare-use/h.h @@ -0,0 +1,7 @@ +#ifndef H_H +#define H_H +#include "c.h" +#include "d.h" // expected-error {{use of a module not declared used}} +#include "h1.h" +const int h1 = aux_h*c*7*d; +#endif diff --git a/test/Modules/Inputs/declare-use/h1.h b/test/Modules/Inputs/declare-use/h1.h new file mode 100644 index 0000000..a9275d5 --- /dev/null +++ b/test/Modules/Inputs/declare-use/h1.h @@ -0,0 +1 @@ +int aux_h = 13; diff --git a/test/Modules/Inputs/declare-use/module.map b/test/Modules/Inputs/declare-use/module.map new file mode 100644 index 0000000..774fc37 --- /dev/null +++ b/test/Modules/Inputs/declare-use/module.map @@ -0,0 +1,43 @@ +module XA { + header "a.h" +} + +module XB { + header "b.h" +} + +module XC { + header "c.h" + use XA +} + +module XD { + header "d.h" + use XA +} + +module XE { + header "e.h" + use XA + use XB +} + +module XF { + header "f.h" + use XA + use XB +} + +module XG { + header "g.h" + header "g1.h" + use XC + use XE +} + +module XH { + header "h.h" + header "h1.h" + use XC + use XE +} diff --git a/test/Modules/Inputs/def.h b/test/Modules/Inputs/def.h index eb7eb7e..6fa83d3 100644 --- a/test/Modules/Inputs/def.h +++ b/test/Modules/Inputs/def.h @@ -17,4 +17,11 @@ class Def2 { public: void func(); }; + +namespace Def3NS { + class Def3 { + public: + void func(); + }; +} #endif diff --git a/test/Modules/Inputs/dummy.h b/test/Modules/Inputs/dummy.h new file mode 100644 index 0000000..6e1ac74 --- /dev/null +++ b/test/Modules/Inputs/dummy.h @@ -0,0 +1,3 @@ +// This module only exists to make local decl IDs and global decl IDs different. + +struct Dummy {} extern *dummy1, *dummy2, *dummy3; diff --git a/test/Modules/Inputs/incomplete_mod.h b/test/Modules/Inputs/incomplete_mod.h new file mode 100644 index 0000000..f08be72 --- /dev/null +++ b/test/Modules/Inputs/incomplete_mod.h @@ -0,0 +1 @@ +#include "incomplete_mod_missing.h" diff --git a/test/Modules/Inputs/incomplete_mod_missing.h b/test/Modules/Inputs/incomplete_mod_missing.h new file mode 100644 index 0000000..ffc85d5 --- /dev/null +++ b/test/Modules/Inputs/incomplete_mod_missing.h @@ -0,0 +1,2 @@ +extern int *missing; + diff --git a/test/Modules/Inputs/initializer_list b/test/Modules/Inputs/initializer_list new file mode 100644 index 0000000..6058f80 --- /dev/null +++ b/test/Modules/Inputs/initializer_list @@ -0,0 +1,9 @@ +namespace std { + using size_t = decltype(sizeof(0)); + + template<typename T> struct initializer_list { + initializer_list(T*, size_t); + }; + + template<typename T> int min(initializer_list<T>); +} diff --git a/test/Modules/Inputs/modular_maps/a.h b/test/Modules/Inputs/modular_maps/a.h new file mode 100644 index 0000000..a36dc1b --- /dev/null +++ b/test/Modules/Inputs/modular_maps/a.h @@ -0,0 +1,4 @@ +#ifndef A_H +#define A_H +const int a = 2; +#endif diff --git a/test/Modules/Inputs/modular_maps/b.h b/test/Modules/Inputs/modular_maps/b.h new file mode 100644 index 0000000..55daf72 --- /dev/null +++ b/test/Modules/Inputs/modular_maps/b.h @@ -0,0 +1,4 @@ +#ifndef B_H +#define B_H +const int b = 3; +#endif diff --git a/test/Modules/Inputs/modular_maps/common.h b/test/Modules/Inputs/modular_maps/common.h new file mode 100644 index 0000000..f690bcb --- /dev/null +++ b/test/Modules/Inputs/modular_maps/common.h @@ -0,0 +1,4 @@ +#ifndef COMMON_H +#define COMMON_H +const int c = 2; +#endif diff --git a/test/Modules/Inputs/modular_maps/modulea.map b/test/Modules/Inputs/modular_maps/modulea.map new file mode 100644 index 0000000..58c5f64 --- /dev/null +++ b/test/Modules/Inputs/modular_maps/modulea.map @@ -0,0 +1,7 @@ +module A { + header "common.h" + header "a.h" +} + +extern module B "moduleb.map" + diff --git a/test/Modules/Inputs/modular_maps/moduleb.map b/test/Modules/Inputs/modular_maps/moduleb.map new file mode 100644 index 0000000..7b35e8f --- /dev/null +++ b/test/Modules/Inputs/modular_maps/moduleb.map @@ -0,0 +1,4 @@ +module B { + header "common.h" + private header "b.h" +} diff --git a/test/Modules/Inputs/module.map b/test/Modules/Inputs/module.map index d20521f..cf8a298 100644 --- a/test/Modules/Inputs/module.map +++ b/test/Modules/Inputs/module.map @@ -131,6 +131,10 @@ module MethodPoolA { module MethodPoolB { header "MethodPoolB.h" + explicit module Sub2 { + header "MethodPoolBSub2.h" + } + explicit module Sub { header "MethodPoolBSub.h" } @@ -184,6 +188,35 @@ module cxx_linkage_cache { header "cxx-linkage-cache.h" } +module cxx_templates_common { + header "cxx-templates-common.h" +} + +module cxx_templates_a { + header "cxx-templates-a.h" +} + +module cxx_templates_b_impl { + header "cxx-templates-b-impl.h" +} + +module cxx_templates_b { + header "cxx-templates-b.h" +} + +module cxx_templates_c { + header "cxx-templates-c.h" +} + +module cxx_decls { + module unimported { + header "cxx-decls-unimported.h" + } + module imported { + header "cxx-decls-imported.h" + } +} + module config { header "config.h" config_macros [exhaustive] WANT_FOO, WANT_BAR @@ -193,6 +226,10 @@ module diag_pragma { header "diag_pragma.h" } +module dummy { + header "dummy.h" +} + module builtin { header "builtin.h" explicit module sub { @@ -209,3 +246,38 @@ module linkage_merge { } } + +module incomplete_mod { + header "incomplete_mod.h" +} + +module warning { + header "warning.h" +} + +module initializer_list { + header "initializer_list" +} + +module using_decl { + module a { header "using-decl-a.h" export * } + module b { header "using-decl-b.h" export * } +} + +module recursive_visibility_a1 { + module inner { header "recursive_visibility_a1_inner.h" } +} +module recursive_visibility_a2 { + module inner { + module more_inner { + header "recursive_visibility_a2_more_inner.h" + } + } +} +module recursive_visibility_b { + header "recursive_visibility_b.h" + export * +} +module recursive_visibility_c { + header "recursive_visibility_c.h" +} diff --git a/test/Modules/Inputs/namespaces-top.h b/test/Modules/Inputs/namespaces-top.h index 0c607f5..7aa8490 100644 --- a/test/Modules/Inputs/namespaces-top.h +++ b/test/Modules/Inputs/namespaces-top.h @@ -12,3 +12,8 @@ namespace N3 { namespace N12 { } +namespace N13 { + void f(); + int f(int); + void (*p)() = &f; +} diff --git a/test/Modules/Inputs/odr/a.h b/test/Modules/Inputs/odr/a.h new file mode 100644 index 0000000..26144b8 --- /dev/null +++ b/test/Modules/Inputs/odr/a.h @@ -0,0 +1,13 @@ +extern struct Y { + int n; + float f; +} y1; +enum E { e1 }; + +struct X { + int n; +} x1; + +int f() { + return y1.n + e1 + y1.f + x1.n; +} diff --git a/test/Modules/Inputs/odr/b.h b/test/Modules/Inputs/odr/b.h new file mode 100644 index 0000000..b406397 --- /dev/null +++ b/test/Modules/Inputs/odr/b.h @@ -0,0 +1,9 @@ +struct Y { + int m; + double f; +} y2; +enum E { e2 }; + +int g() { + return y2.m + e2 + y2.f; +} diff --git a/test/Modules/Inputs/odr/module.map b/test/Modules/Inputs/odr/module.map new file mode 100644 index 0000000..81f3963 --- /dev/null +++ b/test/Modules/Inputs/odr/module.map @@ -0,0 +1,6 @@ +module a { + header "a.h" +} +module b { + header "b.h" +} diff --git a/test/Modules/Inputs/pch-used.h b/test/Modules/Inputs/pch-used.h new file mode 100644 index 0000000..60e0097 --- /dev/null +++ b/test/Modules/Inputs/pch-used.h @@ -0,0 +1,2 @@ +@import cstd.stdio; +static inline void SPXTrace() { fprintf(__stderrp, ""); } diff --git a/test/Modules/Inputs/private/common.h b/test/Modules/Inputs/private/common.h new file mode 100644 index 0000000..17d5444 --- /dev/null +++ b/test/Modules/Inputs/private/common.h @@ -0,0 +1,6 @@ +#ifndef COMMON_H +#define COMMON_H + +typedef int common; + +#endif diff --git a/test/Modules/Inputs/private/module.map b/test/Modules/Inputs/private/module.map new file mode 100644 index 0000000..9da4435 --- /dev/null +++ b/test/Modules/Inputs/private/module.map @@ -0,0 +1,9 @@ +module libPrivate1 { + header "public1.h" + private header "private1.h" +} + +module libPrivate2 { + header "public2.h" + private header "private2.h" +} diff --git a/test/Modules/Inputs/private/private1.h b/test/Modules/Inputs/private/private1.h new file mode 100644 index 0000000..3f41cc0 --- /dev/null +++ b/test/Modules/Inputs/private/private1.h @@ -0,0 +1,9 @@ +#ifndef PRIVATE1_H +#define PRIVATE1_H + +#include "common.h" + +struct mitts_off1 { common field; }; +struct mitts_off1 hidden_variable1; + +#endif diff --git a/test/Modules/Inputs/private/private2.h b/test/Modules/Inputs/private/private2.h new file mode 100644 index 0000000..3b6cddc --- /dev/null +++ b/test/Modules/Inputs/private/private2.h @@ -0,0 +1,9 @@ +#ifndef PRIVATE2_H +#define PRIVATE2_H + +#include "common.h" + +struct mitts_off2 { common field; }; +struct mitts_off2 hidden_variable2; + +#endif diff --git a/test/Modules/Inputs/private/public1.h b/test/Modules/Inputs/private/public1.h new file mode 100644 index 0000000..3af596a --- /dev/null +++ b/test/Modules/Inputs/private/public1.h @@ -0,0 +1,9 @@ +#ifndef PUBLIC1_H +#define PUBLIC1_H + +#include "private1.h" + +struct use_this1 { struct mitts_off1 field; }; +struct use_this1 public_variable1; + +#endif diff --git a/test/Modules/Inputs/private/public2.h b/test/Modules/Inputs/private/public2.h new file mode 100644 index 0000000..03d0a85 --- /dev/null +++ b/test/Modules/Inputs/private/public2.h @@ -0,0 +1,9 @@ +#ifndef PUBLIC2_H +#define PUBLIC2_H + +#include "private2.h" + +struct use_this2 { struct mitts_off2 field; }; +struct use_this2 public_variable2; + +#endif diff --git a/test/Modules/Inputs/private0/common.h b/test/Modules/Inputs/private0/common.h new file mode 100644 index 0000000..17d5444 --- /dev/null +++ b/test/Modules/Inputs/private0/common.h @@ -0,0 +1,6 @@ +#ifndef COMMON_H +#define COMMON_H + +typedef int common; + +#endif diff --git a/test/Modules/Inputs/private1/module.map b/test/Modules/Inputs/private1/module.map new file mode 100644 index 0000000..0904fe6 --- /dev/null +++ b/test/Modules/Inputs/private1/module.map @@ -0,0 +1,4 @@ +module libPrivate { + header "public1.h" + private header "private1.h" +} diff --git a/test/Modules/Inputs/private1/private1.h b/test/Modules/Inputs/private1/private1.h new file mode 100644 index 0000000..3f41cc0 --- /dev/null +++ b/test/Modules/Inputs/private1/private1.h @@ -0,0 +1,9 @@ +#ifndef PRIVATE1_H +#define PRIVATE1_H + +#include "common.h" + +struct mitts_off1 { common field; }; +struct mitts_off1 hidden_variable1; + +#endif diff --git a/test/Modules/Inputs/private1/public1.h b/test/Modules/Inputs/private1/public1.h new file mode 100644 index 0000000..3af596a --- /dev/null +++ b/test/Modules/Inputs/private1/public1.h @@ -0,0 +1,9 @@ +#ifndef PUBLIC1_H +#define PUBLIC1_H + +#include "private1.h" + +struct use_this1 { struct mitts_off1 field; }; +struct use_this1 public_variable1; + +#endif diff --git a/test/Modules/Inputs/private2/module.map b/test/Modules/Inputs/private2/module.map new file mode 100644 index 0000000..3d2a578 --- /dev/null +++ b/test/Modules/Inputs/private2/module.map @@ -0,0 +1,4 @@ +module libPrivateN2 { + header "public2.h" + private header "private2.h" +} diff --git a/test/Modules/Inputs/private2/private2.h b/test/Modules/Inputs/private2/private2.h new file mode 100644 index 0000000..3b6cddc --- /dev/null +++ b/test/Modules/Inputs/private2/private2.h @@ -0,0 +1,9 @@ +#ifndef PRIVATE2_H +#define PRIVATE2_H + +#include "common.h" + +struct mitts_off2 { common field; }; +struct mitts_off2 hidden_variable2; + +#endif diff --git a/test/Modules/Inputs/private2/public2.h b/test/Modules/Inputs/private2/public2.h new file mode 100644 index 0000000..03d0a85 --- /dev/null +++ b/test/Modules/Inputs/private2/public2.h @@ -0,0 +1,9 @@ +#ifndef PUBLIC2_H +#define PUBLIC2_H + +#include "private2.h" + +struct use_this2 { struct mitts_off2 field; }; +struct use_this2 public_variable2; + +#endif diff --git a/test/Modules/Inputs/recursive_visibility_a1_inner.h b/test/Modules/Inputs/recursive_visibility_a1_inner.h new file mode 100644 index 0000000..0f9fdf7 --- /dev/null +++ b/test/Modules/Inputs/recursive_visibility_a1_inner.h @@ -0,0 +1,4 @@ +namespace A1_Inner { + struct X {}; + void f(X); +} diff --git a/test/Modules/Inputs/recursive_visibility_a2_more_inner.h b/test/Modules/Inputs/recursive_visibility_a2_more_inner.h new file mode 100644 index 0000000..a9ff9d9 --- /dev/null +++ b/test/Modules/Inputs/recursive_visibility_a2_more_inner.h @@ -0,0 +1,4 @@ +namespace A2_More_Inner { + struct X {}; + void f(X); +} diff --git a/test/Modules/Inputs/recursive_visibility_b.h b/test/Modules/Inputs/recursive_visibility_b.h new file mode 100644 index 0000000..2c5d4ef --- /dev/null +++ b/test/Modules/Inputs/recursive_visibility_b.h @@ -0,0 +1,2 @@ +@import recursive_visibility_a1.inner; +@import recursive_visibility_a2; diff --git a/test/Modules/Inputs/recursive_visibility_c.h b/test/Modules/Inputs/recursive_visibility_c.h new file mode 100644 index 0000000..a978a3c --- /dev/null +++ b/test/Modules/Inputs/recursive_visibility_c.h @@ -0,0 +1,5 @@ +@import recursive_visibility_b; +template<template<typename T> class Y> void g() { + f(typename Y<A1_Inner::X>::type{}); + f(typename Y<A2_More_Inner::X>::type{}); +} diff --git a/test/Modules/Inputs/separate_map_tree/maps/modulea.map b/test/Modules/Inputs/separate_map_tree/maps/modulea.map new file mode 100644 index 0000000..736503e --- /dev/null +++ b/test/Modules/Inputs/separate_map_tree/maps/modulea.map @@ -0,0 +1,12 @@ +module D { + header "../src/common.h" +} + +module A { + header "../src/common.h" + use C +} + +extern module B "moduleb.map" +extern module C "modulec.map" + diff --git a/test/Modules/Inputs/separate_map_tree/maps/moduleb.map b/test/Modules/Inputs/separate_map_tree/maps/moduleb.map new file mode 100644 index 0000000..d387796 --- /dev/null +++ b/test/Modules/Inputs/separate_map_tree/maps/moduleb.map @@ -0,0 +1,4 @@ +module B { + header "../src/public-in-b.h" + private header "../src/public-in-c.h" +} diff --git a/test/Modules/Inputs/separate_map_tree/maps/modulec.map b/test/Modules/Inputs/separate_map_tree/maps/modulec.map new file mode 100644 index 0000000..91063b6 --- /dev/null +++ b/test/Modules/Inputs/separate_map_tree/maps/modulec.map @@ -0,0 +1,5 @@ +module C { + header "../src/public-in-c.h" + private header "../src/public-in-b.h" + private header "../src/private-in-c.h" +} diff --git a/test/Modules/Inputs/separate_map_tree/src/common.h b/test/Modules/Inputs/separate_map_tree/src/common.h new file mode 100644 index 0000000..1d2ecb5 --- /dev/null +++ b/test/Modules/Inputs/separate_map_tree/src/common.h @@ -0,0 +1,4 @@ +#ifndef COMMON_H +#define COMMON_H +const int common = 2; +#endif diff --git a/test/Modules/Inputs/separate_map_tree/src/private-in-c.h b/test/Modules/Inputs/separate_map_tree/src/private-in-c.h new file mode 100644 index 0000000..bc9e2c1 --- /dev/null +++ b/test/Modules/Inputs/separate_map_tree/src/private-in-c.h @@ -0,0 +1,4 @@ +#ifndef PRIVATE_IN_C_H +#define PRIVATE_IN_C_H +const int c_ = 2; +#endif diff --git a/test/Modules/Inputs/separate_map_tree/src/public-in-b.h b/test/Modules/Inputs/separate_map_tree/src/public-in-b.h new file mode 100644 index 0000000..9ea6c1b --- /dev/null +++ b/test/Modules/Inputs/separate_map_tree/src/public-in-b.h @@ -0,0 +1,4 @@ +#ifndef PUBLIC_IN_B_H +#define PUBLIC_IN_B_H +const int b = 3; +#endif diff --git a/test/Modules/Inputs/separate_map_tree/src/public-in-c.h b/test/Modules/Inputs/separate_map_tree/src/public-in-c.h new file mode 100644 index 0000000..fa3d2fd --- /dev/null +++ b/test/Modules/Inputs/separate_map_tree/src/public-in-c.h @@ -0,0 +1,4 @@ +#ifndef PUBLIC_IN_C_H +#define PUBLIC_IN_C_H +const int c = 2; +#endif diff --git a/test/Modules/Inputs/submodules/import-self-a.h b/test/Modules/Inputs/submodules/import-self-a.h new file mode 100644 index 0000000..adb070a --- /dev/null +++ b/test/Modules/Inputs/submodules/import-self-a.h @@ -0,0 +1 @@ +typedef int MyTypeA; diff --git a/test/Modules/Inputs/submodules/import-self-b.h b/test/Modules/Inputs/submodules/import-self-b.h new file mode 100644 index 0000000..f88b56d --- /dev/null +++ b/test/Modules/Inputs/submodules/import-self-b.h @@ -0,0 +1,10 @@ +@import import_self.c; +#include "import-self-d.h" + +// FIXME: This should not work; names from 'a' should not be visible here. +MyTypeA import_self_test_a; + +// FIXME: This should work but does not; names from 'b' are not actually visible here. +//MyTypeC import_self_test_c; + +MyTypeD import_self_test_d; diff --git a/test/Modules/Inputs/submodules/import-self-c.h b/test/Modules/Inputs/submodules/import-self-c.h new file mode 100644 index 0000000..f4b86c5 --- /dev/null +++ b/test/Modules/Inputs/submodules/import-self-c.h @@ -0,0 +1 @@ +typedef int MyTypeC; diff --git a/test/Modules/Inputs/submodules/import-self-d.h b/test/Modules/Inputs/submodules/import-self-d.h new file mode 100644 index 0000000..e32a6f5 --- /dev/null +++ b/test/Modules/Inputs/submodules/import-self-d.h @@ -0,0 +1 @@ +typedef int MyTypeD; diff --git a/test/Modules/Inputs/submodules/module.map b/test/Modules/Inputs/submodules/module.map index 16cedac..c91e94f 100644 --- a/test/Modules/Inputs/submodules/module.map +++ b/test/Modules/Inputs/submodules/module.map @@ -3,3 +3,10 @@ module std { module type_traits { header "type_traits.h" } explicit module hash_map { header "hash_map.h" } } + +module import_self { + module a { header "import-self-a.h" } + module b { header "import-self-b.h" export * } + module c { header "import-self-c.h" } + module d { header "import-self-d.h" } +} diff --git a/test/Modules/Inputs/templates-left.h b/test/Modules/Inputs/templates-left.h index 7451420..e76598d 100644 --- a/test/Modules/Inputs/templates-left.h +++ b/test/Modules/Inputs/templates-left.h @@ -19,6 +19,10 @@ namespace N { }; } +constexpr unsigned List<int>::*size_left = &List<int>::size; +List<int> list_left = { 0, 8 }; +typedef List<int> ListInt_left; + template <typename T> void pendingInstantiationEmit(T) {} void triggerPendingInstantiation() { @@ -27,3 +31,5 @@ void triggerPendingInstantiation() { } void redeclDefinitionEmit(){} + +typedef Outer<int>::Inner OuterIntInner_left; diff --git a/test/Modules/Inputs/templates-right.h b/test/Modules/Inputs/templates-right.h index d3524d3..16d0a71 100644 --- a/test/Modules/Inputs/templates-right.h +++ b/test/Modules/Inputs/templates-right.h @@ -18,6 +18,10 @@ namespace N { }; } +constexpr unsigned List<int>::*size_right = &List<int>::size; +List<int> list_right = { 0, 12 }; +typedef List<int> ListInt_right; + template <typename T> void pendingInstantiationEmit(T) {} void triggerPendingInstantiationToo() { @@ -25,3 +29,5 @@ void triggerPendingInstantiationToo() { } void redeclDefinitionEmit(){} + +typedef Outer<int>::Inner OuterIntInner_right; diff --git a/test/Modules/Inputs/templates-top.h b/test/Modules/Inputs/templates-top.h index 5985ee8..87dcd8b 100644 --- a/test/Modules/Inputs/templates-top.h +++ b/test/Modules/Inputs/templates-top.h @@ -3,6 +3,10 @@ template<typename T> class Vector; template<typename T> class List { public: void push_back(T); + + struct node {}; + node *head; + unsigned size; }; namespace A { @@ -15,3 +19,7 @@ template <typename T> class A::WhereAmI { public: static void func() {} }; + +template<typename T> struct Outer { + struct Inner {}; +}; diff --git a/test/Modules/Inputs/using-decl-a.h b/test/Modules/Inputs/using-decl-a.h new file mode 100644 index 0000000..85a4788 --- /dev/null +++ b/test/Modules/Inputs/using-decl-a.h @@ -0,0 +1,10 @@ +typedef int using_decl_type; +int using_decl_var; + +namespace UsingDecl { + using ::using_decl_type; + using ::using_decl_var; + + namespace A { typedef int inner; } + using A::inner; +} diff --git a/test/Modules/Inputs/using-decl-b.h b/test/Modules/Inputs/using-decl-b.h new file mode 100644 index 0000000..b82526f --- /dev/null +++ b/test/Modules/Inputs/using-decl-b.h @@ -0,0 +1,11 @@ +namespace UsingDecl { + namespace B { typedef int inner; } + using B::inner; +} + +#include "using-decl-a.h" + +namespace UsingDecl { + using ::using_decl_type; + using ::using_decl_var; +} diff --git a/test/Modules/Inputs/warning.h b/test/Modules/Inputs/warning.h new file mode 100644 index 0000000..a90c628 --- /dev/null +++ b/test/Modules/Inputs/warning.h @@ -0,0 +1 @@ +enum { bigger_than_int = 0x80000000 }; diff --git a/test/Modules/auto-module-import.m b/test/Modules/auto-module-import.m index 7351828..d7fb9d1 100644 --- a/test/Modules/auto-module-import.m +++ b/test/Modules/auto-module-import.m @@ -1,10 +1,12 @@ // RUN: rm -rf %t +// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -F %S/Inputs %s -verify -DERRORS // RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -F %S/Inputs %s -verify +// +// Test both with and without the declarations that refer to unimported +// entities. For error recovery, those cases implicitly trigger an import. #include <DependsOnModule/DependsOnModule.h> // expected-warning{{treating #include as an import of module 'DependsOnModule'}} -// expected-note@Inputs/NoUmbrella.framework/PrivateHeaders/A_Private.h:1{{'no_umbrella_A_private' declared here}} - #ifdef MODULE_H_MACRO # error MODULE_H_MACRO should have been hidden #endif @@ -13,15 +15,21 @@ # error DEPENDS_ON_MODULE should have been hidden #endif -Module *mod; // expected-error{{unknown type name 'Module'}} - +#ifdef ERRORS +Module *mod; // expected-error{{declaration of 'Module' must be imported from module 'Module' before it is required}} +// expected-note@Inputs/Module.framework/Headers/Module.h:15 {{previous}} +#else #import <AlsoDependsOnModule/AlsoDependsOnModule.h> // expected-warning{{treating #import as an import of module 'AlsoDependsOnModule'}} +#endif Module *mod2; int getDependsOther() { return depends_on_module_other; } void testSubframeworkOther() { - double *sfo1 = sub_framework_other; // expected-error{{use of undeclared identifier 'sub_framework_other'}} +#ifdef ERRORS + double *sfo1 = sub_framework_other; // expected-error{{declaration of 'sub_framework_other' must be imported from module 'DependsOnModule.SubFramework.Other'}} + // expected-note@Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/Other.h:15 {{previous}} +#endif } // Test umbrella-less submodule includes @@ -32,8 +40,10 @@ int getNoUmbrellaA() { return no_umbrella_A; } #include <NoUmbrella/SubDir/C.h> // expected-warning{{treating #include as an import of module 'NoUmbrella.SubDir.C'}} int getNoUmbrellaC() { return no_umbrella_C; } +#ifndef ERRORS // Test header cross-subframework include pattern. #include <DependsOnModule/../Frameworks/SubFramework.framework/Headers/Other.h> // expected-warning{{treating #include as an import of module 'DependsOnModule.SubFramework.Other'}} +#endif void testSubframeworkOtherAgain() { double *sfo1 = sub_framework_other; @@ -61,7 +71,8 @@ int getModulePrivate() { return module_private; } #include <NoUmbrella/A_Private.h> // expected-warning{{treating #include as an import of module 'NoUmbrella.Private.A_Private'}} int getNoUmbrellaAPrivate() { return no_umbrella_A_private; } -int getNoUmbrellaBPrivateFail() { return no_umbrella_B_private; } // expected-error{{use of undeclared identifier 'no_umbrella_B_private'; did you mean 'no_umbrella_A_private'?}} +int getNoUmbrellaBPrivateFail() { return no_umbrella_B_private; } // expected-error{{declaration of 'no_umbrella_B_private' must be imported from module 'NoUmbrella.Private.B_Private'}} +// expected-note@Inputs/NoUmbrella.framework/PrivateHeaders/B_Private.h:1 {{previous}} // Test inclusion of headers that are under an umbrella directory but // not actually part of the module. @@ -71,3 +82,7 @@ int getNoUmbrellaBPrivateFail() { return no_umbrella_B_private; } // expected-er int getNotInModule() { return not_in_module; } + +void includeNotAtTopLevel() { + #include <NoUmbrella/A.h> // expected-warning {{treating #include as an import}} expected-error {{expected expression}} +} diff --git a/test/Modules/autolink.m b/test/Modules/autolink.m index 4bf9d59..077aac5 100644 --- a/test/Modules/autolink.m +++ b/test/Modules/autolink.m @@ -35,7 +35,7 @@ int use_no_umbrella() { // CHECK: !4 = metadata !{i32 6, metadata !"Linker Options", metadata ![[AUTOLINK_OPTIONS:[0-9]+]]} // CHECK: ![[AUTOLINK_OPTIONS]] = metadata !{metadata ![[AUTOLINK_FRAMEWORK:[0-9]+]], metadata ![[AUTOLINK:[0-9]+]], metadata ![[DEPENDSONMODULE:[0-9]+]], metadata ![[MODULE:[0-9]+]], metadata ![[NOUMBRELLA:[0-9]+]]} // CHECK: ![[AUTOLINK_FRAMEWORK]] = metadata !{metadata !"-framework", metadata !"autolink_framework"} -// CHECK: ![[AUTOLINK]] = metadata !{metadata !"-lautolink"} +// CHECK: ![[AUTOLINK]] = metadata !{metadata !"{{(-l|/DEFAULTLIB:)}}autolink{{(\.lib)?}}"} // CHECK: ![[DEPENDSONMODULE]] = metadata !{metadata !"-framework", metadata !"DependsOnModule"} // CHECK: ![[MODULE]] = metadata !{metadata !"-framework", metadata !"Module"} // CHECK: ![[NOUMBRELLA]] = metadata !{metadata !"-framework", metadata !"NoUmbrella"} diff --git a/test/Modules/build-fail-notes.m b/test/Modules/build-fail-notes.m index 8375788..e273411 100644 --- a/test/Modules/build-fail-notes.m +++ b/test/Modules/build-fail-notes.m @@ -1,5 +1,5 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -F %S/Inputs -DgetModuleVersion="epic fail" %s 2>&1 | FileCheck %s +// RUN: not %clang_cc1 -fmodules-cache-path=%t -fmodules -F %S/Inputs -DgetModuleVersion="epic fail" %s 2>&1 | FileCheck %s @import DependsOnModule; @@ -11,14 +11,14 @@ // CHECK: fatal error: could not build module 'DependsOnModule' // CHECK-NOT: error: -// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -F %S/Inputs %s -fdiagnostics-show-note-include-stack 2>&1 | FileCheck -check-prefix=CHECK-REDEF %s +// RUN: not %clang_cc1 -fmodules-cache-path=%t -fmodules -F %S/Inputs %s -fdiagnostics-show-note-include-stack 2>&1 | FileCheck -check-prefix=CHECK-REDEF %s extern int Module; // CHECK-REDEF: In module 'DependsOnModule' imported from // CHECK-REDEF: In module 'Module' imported from // CHECK-REDEF: Module.h:15:12: note: previous definition is here -// RUN: not %clang_cc1 -fmodules-cache-path=%t -fmodules -F %S/Inputs -DgetModuleVersion="epic fail" -serialize-diagnostic-file %t/tmp.diag %s 2>&1 +// RUN: not %clang_cc1 -Wincomplete-umbrella -fmodules-cache-path=%t -fmodules -F %S/Inputs -DgetModuleVersion="epic fail" -serialize-diagnostic-file %t/tmp.diag %s 2>&1 // RUN: c-index-test -read-diagnostics %t/tmp.diag 2>&1 | FileCheck -check-prefix=CHECK-SDIAG %s // CHECK-SDIAG: Module.h:9:13: error: expected ';' after top level declarator diff --git a/test/Modules/compiler_builtins_arm.m b/test/Modules/compiler_builtins_arm.m new file mode 100644 index 0000000..d15437c --- /dev/null +++ b/test/Modules/compiler_builtins_arm.m @@ -0,0 +1,6 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fsyntax-only -triple thumbv7-none-linux-gnueabihf -target-abi aapcs -target-cpu cortex-a8 -mfloat-abi hard -std=c99 -fmodules -fmodules-cache-path=%t -D__need_wint_t %s -verify +// expected-no-diagnostics +// REQUIRES: arm-registered-target + +@import _Builtin_intrinsics.arm.neon; diff --git a/test/Modules/cxx-decls.cpp b/test/Modules/cxx-decls.cpp new file mode 100644 index 0000000..ba3281a --- /dev/null +++ b/test/Modules/cxx-decls.cpp @@ -0,0 +1,21 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11 + +// expected-no-diagnostics + +@import dummy; +@import cxx_decls.imported; + +void test_delete(int *p) { + // We can call the normal global deallocation function even though it has only + // ever been explicitly declared in an unimported submodule. + delete p; +} + +void friend_1(HasFriends s) { + s.private_thing(); +} +void test_friends(HasFriends s) { + friend_1(s); + friend_2(s); +} diff --git a/test/Modules/cxx-templates.cpp b/test/Modules/cxx-templates.cpp new file mode 100644 index 0000000..65f41f6 --- /dev/null +++ b/test/Modules/cxx-templates.cpp @@ -0,0 +1,125 @@ +// RUN: rm -rf %t +// RUN: not %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -std=c++11 -ast-dump -ast-dump-lookups | FileCheck %s --check-prefix=CHECK-GLOBAL +// RUN: not %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -std=c++11 -ast-dump -ast-dump-lookups -ast-dump-filter N | FileCheck %s --check-prefix=CHECK-NAMESPACE-N +// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11 + +@import cxx_templates_a; +@import cxx_templates_b; +@import cxx_templates_c; +@import cxx_templates_common; + +template<typename, char> struct Tmpl_T_C {}; +template<typename, int, int> struct Tmpl_T_I_I {}; + +template<typename A, typename B, A> struct Tmpl_T_T_A {}; +template<typename A, typename B, B> struct Tmpl_T_T_B {}; + +template<int> struct UseInt {}; + +void g() { + f(0); + 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}} + + N::f(0); + N::f<double>(1.0); + N::f<int>(); + N::f(); // expected-error {{no matching function}} + // expected-note@Inputs/cxx-templates-b.h:6 {{couldn't infer template argument}} + // expected-note@Inputs/cxx-templates-b.h:7 {{requires single argument 't'}} + + template_param_kinds_1<0>(); // ok, from cxx-templates-a.h + template_param_kinds_1<int>(); // ok, from cxx-templates-b.h + + template_param_kinds_2<Tmpl_T_C>(); // expected-error {{no matching function}} + // expected-note@Inputs/cxx-templates-a.h:11 {{invalid explicitly-specified argument}} + // expected-note@Inputs/cxx-templates-b.h:11 {{invalid explicitly-specified argument}} + + template_param_kinds_2<Tmpl_T_I_I>(); // expected-error {{ambiguous}} + // expected-note@Inputs/cxx-templates-a.h:11 {{candidate}} + // expected-note@Inputs/cxx-templates-b.h:11 {{candidate}} + + // FIXME: This should be valid, but we incorrectly match the template template + // argument against both template template parameters. + template_param_kinds_3<Tmpl_T_T_A>(); // expected-error {{ambiguous}} + // expected-note@Inputs/cxx-templates-a.h:12 {{candidate}} + // expected-note@Inputs/cxx-templates-b.h:12 {{candidate}} + template_param_kinds_3<Tmpl_T_T_B>(); // expected-error {{ambiguous}} + // expected-note@Inputs/cxx-templates-a.h:12 {{candidate}} + // expected-note@Inputs/cxx-templates-b.h:12 {{candidate}} + + // Trigger the instantiation of a template in 'a' that uses a type defined in + // 'common'. That type is not visible here. + PerformDelayedLookup(defined_in_common); + + // Likewise, but via a default argument. + PerformDelayedLookupInDefaultArgument(defined_in_common); + + // Trigger the instantiation of a template in 'b' that uses a type defined in + // 'b_impl'. That type is not visible here. + UseDefinedInBImpl<int>(); + + // Trigger the instantiation of a template in 'a' that uses a type defined in + // 'b_impl', via a template defined in 'b'. Since the type is visible from + // within 'b', the instantiation succeeds. + UseDefinedInBImplIndirectly(defined_in_b_impl); + + // Trigger the instantiation of a template in 'a' that uses a type defined in + // 'b_impl'. That type is not visible here, nor in 'a'. This fails; there is + // no reason why DefinedInBImpl should be visible here. + // expected-error@Inputs/cxx-templates-a.h:19 {{definition of 'DefinedInBImpl' must be imported}} + // expected-note@Inputs/cxx-templates-b-impl.h:1 {{definition is here}} + PerformDelayedLookup(defined_in_b_impl); // expected-note {{in instantiation of}} + + merge_templates_a = merge_templates_b; // ok, same type + + using T = decltype(enum_a_from_a); + using T = decltype(enum_b_from_b); + T e = true ? enum_a_from_a : enum_b_from_b; + + UseRedeclaredEnum<int>(UseInt<1>()); + // FIXME: Reintroduce this once we merge function template specializations. + //static_assert(UseRedeclaredEnumA == UseRedeclaredEnumB, ""); + //static_assert(UseRedeclaredEnumA == UseRedeclaredEnum<int>, ""); + //static_assert(UseRedeclaredEnumB == UseRedeclaredEnum<int>, ""); + static_assert(enum_c_from_a == enum_c_from_b, ""); + CommonTemplate<int> cti; + CommonTemplate<int>::E eee = CommonTemplate<int>::c; +} + +RedeclaredAsFriend<int> raf1; +RedeclareTemplateAsFriend<double> rtaf; +RedeclaredAsFriend<double> raf2; + +MergeSpecializations<int*>::partially_specialized_in_a spec_in_a_1; +MergeSpecializations<int&>::partially_specialized_in_b spec_in_b_1; +MergeSpecializations<int[]>::partially_specialized_in_c spec_in_c_1; +MergeSpecializations<char>::explicitly_specialized_in_a spec_in_a_2; +MergeSpecializations<double>::explicitly_specialized_in_b spec_in_b_2; +MergeSpecializations<bool>::explicitly_specialized_in_c spec_in_c_2; + +@import cxx_templates_common; + +typedef SomeTemplate<int*> SomeTemplateIntPtr; +typedef SomeTemplate<int&> SomeTemplateIntRef; +SomeTemplate<char*> some_template_char_ptr; +SomeTemplate<char&> some_template_char_ref; + +void testImplicitSpecialMembers(SomeTemplate<char[1]> &a, + const SomeTemplate<char[1]> &b, + SomeTemplate<char[2]> &c, + const SomeTemplate<char[2]> &d) { + a = b; + c = d; +} + +// CHECK-GLOBAL: DeclarationName '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' diff --git a/test/Modules/cycles.c b/test/Modules/cycles.c index 5f83092..47728d8 100644 --- a/test/Modules/cycles.c +++ b/test/Modules/cycles.c @@ -1,5 +1,5 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -F %S/Inputs %s 2>&1 | FileCheck %s +// RUN: not %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -F %S/Inputs %s 2>&1 | FileCheck %s // FIXME: When we have a syntax for modules in C, use that. @import MutuallyRecursive1; diff --git a/test/Modules/declare-use1.cpp b/test/Modules/declare-use1.cpp new file mode 100644 index 0000000..4508017 --- /dev/null +++ b/test/Modules/declare-use1.cpp @@ -0,0 +1,7 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -x objective-c++ -fmodules-cache-path=%t -fmodules -fmodules-decluse -fmodule-name=XG -I %S/Inputs/declare-use %s -verify + +#include "g.h" +#include "e.h" +#include "f.h" // expected-error {{use of a module not declared used}} +const int g2 = g1+e+f; diff --git a/test/Modules/declare-use2.cpp b/test/Modules/declare-use2.cpp new file mode 100644 index 0000000..a2ec55e --- /dev/null +++ b/test/Modules/declare-use2.cpp @@ -0,0 +1,7 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -x objective-c++ -fmodules-cache-path=%t -fmodules -fmodules-decluse -fmodule-name=XH -I %S/Inputs/declare-use %s -verify + +#include "h.h" +#include "e.h" +#include "f.h" // expected-error {{use of a module not declared used}} +const int h2 = h1+e+f; diff --git a/test/Modules/decldef.m b/test/Modules/decldef.m index 7ed82b5..efd2d7c 100644 --- a/test/Modules/decldef.m +++ b/test/Modules/decldef.m @@ -1,13 +1,16 @@ // RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_EARLY // RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -// expected-note@Inputs/def.h:5 {{previous definition is here}} +// expected-note@Inputs/def.h:5 {{previous}} @class Def; Def *def; @import decldef; -A *a1; // expected-error{{unknown type name 'A'}} +#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'}} @import decldef.Decl; @@ -15,7 +18,10 @@ A *a2; struct B *b; void testA(A *a) { - a->ivar = 17; // expected-error{{definition of 'A' must be imported from module 'decldef.Def' before it is required}} + a->ivar = 17; +#ifndef USE_EARLY + // expected-error@-2{{definition of 'A' must be imported from module 'decldef.Def' before it is required}} +#endif } void testB() { diff --git a/test/Modules/decldef.mm b/test/Modules/decldef.mm index 593f53b..3569493 100644 --- a/test/Modules/decldef.mm +++ b/test/Modules/decldef.mm @@ -1,27 +1,35 @@ // RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_EARLY // RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -// expected-note@Inputs/def.h:5 {{previous definition is here}} +// expected-note@Inputs/def.h:5 {{previous}} @class Def; Def *def; -class Def2; +class Def2; // expected-note {{forward decl}} Def2 *def2; +namespace Def3NS { class Def3; } // expected-note {{forward decl}} +Def3NS::Def3 *def3; @interface Unrelated - defMethod; @end @import decldef; -A *a1; // expected-error{{unknown type name 'A'}} -B *b1; // expected-error{{unknown type name 'B'}} +#ifdef USE_EARLY +A *a1; // expected-error{{declaration of 'A' must be imported from module 'decldef.Def'}} +B *b1; +#endif @import decldef.Decl; A *a2; B *b; void testA(A *a) { - a->ivar = 17; // expected-error{{definition of 'A' must be imported from module 'decldef.Def' before it is required}} + a->ivar = 17; +#ifndef USE_EARLY + // expected-error@-2{{definition of 'A' must be imported from module 'decldef.Def' before it is required}} +#endif } void testB() { @@ -33,5 +41,9 @@ void testDef() { } void testDef2() { - def2->func(); + // FIXME: These should both work, since we've (implicitly) imported + // decldef.Def here, but they don't, because nothing has triggered the lazy + // loading of the definitions of these classes. + def2->func(); // expected-error {{incomplete}} + def3->func(); // expected-error {{incomplete}} } diff --git a/test/Modules/driver.c b/test/Modules/driver.c index 08fdaab..79d1bbe 100644 --- a/test/Modules/driver.c +++ b/test/Modules/driver.c @@ -1,5 +1,5 @@ -// RUN: %clang -fmodules %s -### 2>&1 | FileCheck -check-prefix NO_MODULE_CACHE %s -// RUN: %clang -fmodules -fmodules-cache-path=blarg %s -### 2>&1 | FileCheck -check-prefix WITH_MODULE_CACHE %s +// RUN: %clang -fmodules %s -### 2>&1 | FileCheck -check-prefix CHECK-NO_MODULE_CACHE %s +// RUN: %clang -fmodules -fmodules-cache-path=blarg %s -### 2>&1 | FileCheck -check-prefix CHECK-WITH_MODULE_CACHE %s // CHECK-NO_MODULE_CACHE: {{clang.*"-fmodules-cache-path=.*ModuleCache"}} diff --git a/test/Modules/epic-fail.m b/test/Modules/epic-fail.m index 8969149..7ce9571 100644 --- a/test/Modules/epic-fail.m +++ b/test/Modules/epic-fail.m @@ -1,5 +1,5 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -F %S/Inputs -DgetModuleVersion="epic fail" %s 2>&1 | FileCheck %s +// RUN: not %clang_cc1 -fmodules-cache-path=%t -fmodules -F %S/Inputs -DgetModuleVersion="epic fail" %s 2>&1 | FileCheck %s @import Module; @import DependsOnModule; diff --git a/test/Modules/fatal-module-loader-error.m b/test/Modules/fatal-module-loader-error.m new file mode 100644 index 0000000..6af3b4c --- /dev/null +++ b/test/Modules/fatal-module-loader-error.m @@ -0,0 +1,26 @@ +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: touch %t/Module.pcm +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t %s -fdisable-module-hash -F %S/Inputs -verify +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t %s -fdisable-module-hash -F %S/Inputs -DIMPLICIT -verify + +// This tests that after a fatal module loader error, we do not continue parsing. + +#ifdef IMPLICIT + +// expected-error@+1{{does not appear to be}} +#import <Module/Module.h> +#pragma clang __debug crash; + +#else + +// expected-error@+1{{does not appear to be}} +@import Module; +#pragma clang __debug crash; + +#endif + +// Also check that libclang does not create a PCH with such an error. +// RUN: not c-index-test -write-pch %t.pch -fmodules -fmodules-cache-path=%t \ +// RUN: %s -Xclang -fdisable-module-hash -F %S/Inputs 2>&1 | FileCheck %s +// CHECK: Unable to write PCH file diff --git a/test/Modules/import-decl.cpp b/test/Modules/import-decl.cpp index 900e090..56428b3 100644 --- a/test/Modules/import-decl.cpp +++ b/test/Modules/import-decl.cpp @@ -8,3 +8,12 @@ int main() { return 0; } + +// <rdar://problem/15084587> +@interface A +-method; +@end + +void testImport(A *import) { + [import method]; +} diff --git a/test/Modules/incomplete-module.m b/test/Modules/incomplete-module.m new file mode 100644 index 0000000..8edaea9 --- /dev/null +++ b/test/Modules/incomplete-module.m @@ -0,0 +1,5 @@ +@import incomplete_mod; + +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules-cache-path=%t -Wincomplete-module -fmodules -I %S/Inputs %s 2>&1 | FileCheck %s +// CHECK: {{warning: header '.*incomplete_mod_missing.h' is included in module 'incomplete_mod' but not listed in module map}} diff --git a/test/Modules/initializer_list.cpp b/test/Modules/initializer_list.cpp new file mode 100644 index 0000000..0cbcbbb --- /dev/null +++ b/test/Modules/initializer_list.cpp @@ -0,0 +1,7 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11 + +// expected-no-diagnostics +@import initializer_list; + +int n = std::min({1, 2, 3}); diff --git a/test/Modules/load_failure.c b/test/Modules/load_failure.c index 6f9426a..6c6d812 100644 --- a/test/Modules/load_failure.c +++ b/test/Modules/load_failure.c @@ -8,7 +8,7 @@ // RUN: rm -rf %t // RUN: %clang_cc1 -fmodules -x objective-c++ -fmodules-cache-path=%t -fdisable-module-hash -emit-module -fmodule-name=load_failure %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -fdisable-module-hash %s -DNONEXISTENT 2>&1 | FileCheck -check-prefix=CHECK-NONEXISTENT %s +// RUN: not %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -fdisable-module-hash %s -DNONEXISTENT 2>&1 | FileCheck -check-prefix=CHECK-NONEXISTENT %s // CHECK-NONEXISTENT: load_failure.c:2:9: fatal error: module 'load_nonexistent' not found // RUN: not %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -fdisable-module-hash %s -DFAILURE 2> %t.out diff --git a/test/Modules/macros.c b/test/Modules/macros.c index 433e033..541c95b 100644 --- a/test/Modules/macros.c +++ b/test/Modules/macros.c @@ -4,7 +4,7 @@ // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=macros_right %S/Inputs/module.map // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=macros %S/Inputs/module.map // RUN: %clang_cc1 -fmodules -x objective-c -verify -fmodules-cache-path=%t %s -// RUN: %clang_cc1 -E -fmodules -x objective-c -fmodules-cache-path=%t %s | FileCheck -check-prefix CHECK-PREPROCESSED %s +// RUN: not %clang_cc1 -E -fmodules -x objective-c -fmodules-cache-path=%t %s | FileCheck -check-prefix CHECK-PREPROCESSED %s // FIXME: When we have a syntax for modules in C, use that. // These notes come from headers in modules, and are bogus. diff --git a/test/Modules/method_pool.m b/test/Modules/method_pool.m index 6fd74b0..f7d5ae7 100644 --- a/test/Modules/method_pool.m +++ b/test/Modules/method_pool.m @@ -47,6 +47,10 @@ void testMethod3Again(id object) { char *str = [object method3]; // okay: only found in MethodPoolB.Sub } +void testMethod6(id object) { + [object method6]; +} + @import MethodPoolA.Sub; void testMethod3AgainAgain(id object) { diff --git a/test/Modules/modular_maps.cpp b/test/Modules/modular_maps.cpp new file mode 100644 index 0000000..9c9aba8 --- /dev/null +++ b/test/Modules/modular_maps.cpp @@ -0,0 +1,8 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -x objective-c++ -fmodules-cache-path=%t -fmodules -fmodule-map-file=%S/Inputs/modular_maps/modulea.map -I %S/Inputs/modular_maps %s -verify + +#include "common.h" +#include "a.h" +#include "b.h" // expected-error {{private header}} +const int v = a + c; +const int val = a + b + c; // expected-error {{undeclared identifier}} diff --git a/test/Modules/namespaces.cpp b/test/Modules/namespaces.cpp index 426e002..8c225e0 100644 --- a/test/Modules/namespaces.cpp +++ b/test/Modules/namespaces.cpp @@ -75,3 +75,10 @@ void testAnonymousNotMerged() { // expected-note@Inputs/namespaces-right.h:60 {{passing argument to parameter here}} // expected-note@Inputs/namespaces-right.h:67 {{passing argument to parameter here}} + +// Test that bringing in one name from an overload set does not hide the rest. +void testPartialImportOfOverloadSet() { + void (*p)() = N13::p; + p(); + N13::f(0); +} diff --git a/test/Modules/normal-module-map.cpp b/test/Modules/normal-module-map.cpp index 8155318..70fed60 100644 --- a/test/Modules/normal-module-map.cpp +++ b/test/Modules/normal-module-map.cpp @@ -24,8 +24,8 @@ int testNestedUmbrellaA() { int testNestedUmbrellaBFail() { return nested_umbrella_b; - // expected-error@-1{{use of undeclared identifier 'nested_umbrella_b'; did you mean 'nested_umbrella_a'?}} - // expected-note@Inputs/normal-module-map/nested_umbrella/a.h:1{{'nested_umbrella_a' declared here}} + // expected-error@-1{{declaration of 'nested_umbrella_b' must be imported from module 'nested_umbrella.b' before it is required}} + // expected-note@Inputs/normal-module-map/nested_umbrella/b.h:1{{previous}} } @import nested_umbrella.b; diff --git a/test/Modules/objc-categories.m b/test/Modules/objc-categories.m index 81fb28b..f08b13a 100644 --- a/test/Modules/objc-categories.m +++ b/test/Modules/objc-categories.m @@ -10,6 +10,7 @@ // expected-note@Inputs/category_left.h:14 {{previous definition}} // expected-warning@Inputs/category_right.h:11 {{duplicate definition of category}} +// expected-note@Inputs/category_top.h:1 {{receiver is instance of class declared here}} @interface Foo(Source) -(void)source; diff --git a/test/Modules/odr.cpp b/test/Modules/odr.cpp new file mode 100644 index 0000000..5ab10d2 --- /dev/null +++ b/test/Modules/odr.cpp @@ -0,0 +1,20 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs/odr %s -verify -std=c++11 + +// expected-error@a.h:8 {{'X::n' from module 'a' is not present in definition of 'X' provided earlier}} +struct X { // expected-note {{definition has no member 'n'}} +}; + +@import a; +@import b; + +// Trigger the declarations from a and b to be imported. +int x = f() + g(); + +// expected-note@a.h:5 {{definition has no member 'e2'}} +// expected-note@a.h:3 {{declaration of 'f' does not match}} +// expected-note@a.h:1 {{definition has no member 'm'}} + +// expected-error@b.h:5 {{'E::e2' from module 'b' is not present in definition of 'E' in module 'a'}} +// expected-error@b.h:3 {{'Y::f' from module 'b' is not present in definition of 'Y' in module 'a'}} +// expected-error@b.h:2 {{'Y::m' from module 'b' is not present in definition of 'Y' in module 'a'}} diff --git a/test/Modules/pch-used.m b/test/Modules/pch-used.m new file mode 100644 index 0000000..56961ba --- /dev/null +++ b/test/Modules/pch-used.m @@ -0,0 +1,8 @@ +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: %clang_cc1 -x objective-c-header -emit-pch %S/Inputs/pch-used.h -o %t/pch-used.h.pch -fmodules -fmodules-cache-path=%t/cache -O0 -isystem %S/Inputs/System/usr/include +// RUN: %clang_cc1 %s -include-pch %t/pch-used.h.pch -fmodules -fmodules-cache-path=%t/cache -O0 -isystem %S/Inputs/System/usr/include -emit-llvm -o - | FileCheck %s + +void f() { SPXTrace(); } + +// CHECK: define internal void @SPXTrace diff --git a/test/Modules/private.cpp b/test/Modules/private.cpp new file mode 100644 index 0000000..93b4b94 --- /dev/null +++ b/test/Modules/private.cpp @@ -0,0 +1,13 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -x objective-c -fmodules-cache-path=%t -fmodules -I %S/Inputs/private %s -verify + +#include "common.h" +@import libPrivate1; +#include "private1.h" // expected-error {{use of private header from outside its module}} +#include "public2.h" +#include "private2.h" // expected-error {{use of private header from outside its module}} + +struct use_this1 client_variable1; +struct use_this2 client_variable2; +struct mitts_off1 client_variable3; +struct mitts_off2 client_variable4; diff --git a/test/Modules/private1.cpp b/test/Modules/private1.cpp new file mode 100644 index 0000000..811a233 --- /dev/null +++ b/test/Modules/private1.cpp @@ -0,0 +1,13 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -x objective-c -fmodules-cache-path=%t -fmodules -I %S/Inputs/private0 -I %S/Inputs/private1 -I %S/Inputs/private2 %s -verify + +#include "common.h" +@import libPrivateN2; +#include "private1.h" // expected-error {{use of private header from outside its module}} +#include "public2.h" +#include "private2.h" // expected-error {{use of private header from outside its module}} + +struct use_this1 client_variable1; +struct use_this2 client_variable2; +struct mitts_off1 client_variable3; +struct mitts_off2 client_variable4; diff --git a/test/Modules/recursive_visibility.mm b/test/Modules/recursive_visibility.mm new file mode 100644 index 0000000..f37410a --- /dev/null +++ b/test/Modules/recursive_visibility.mm @@ -0,0 +1,9 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11 + +// expected-no-diagnostics + +@import recursive_visibility_c; + +template<typename T> struct Z { typedef T type; }; +template void g<Z>(); diff --git a/test/Modules/requires.m b/test/Modules/requires.m index 83b524d..b8b2c55 100644 --- a/test/Modules/requires.m +++ b/test/Modules/requires.m @@ -2,4 +2,5 @@ // RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -F %S/Inputs %s -verify @import DependsOnModule.CXX; // expected-error{{module 'DependsOnModule.CXX' requires feature 'cplusplus'}} - +@import DependsOnModule.NotCXX; +@import DependsOnModule.NotObjC; // expected-error{{module 'DependsOnModule.NotObjC' is incompatible with feature 'objc'}} diff --git a/test/Modules/requires.mm b/test/Modules/requires.mm new file mode 100644 index 0000000..736f2fa --- /dev/null +++ b/test/Modules/requires.mm @@ -0,0 +1,6 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -F %S/Inputs %s -verify + +@import DependsOnModule.CXX; +@import DependsOnModule.NotCXX; // expected-error{{module 'DependsOnModule.NotCXX' is incompatible with feature 'cplusplus'}} +@import DependsOnModule.NotObjC; // expected-error{{module 'DependsOnModule.NotObjC' is incompatible with feature 'objc'}} diff --git a/test/Modules/self-import-header/af.framework/Headers/a1.h b/test/Modules/self-import-header/af.framework/Headers/a1.h new file mode 100644 index 0000000..31ae279 --- /dev/null +++ b/test/Modules/self-import-header/af.framework/Headers/a1.h @@ -0,0 +1,4 @@ +@import DepBuiltin; + +@interface Foo +@end diff --git a/test/Modules/self-import-header/af.framework/Headers/a2.h b/test/Modules/self-import-header/af.framework/Headers/a2.h new file mode 100644 index 0000000..cc7e6e2 --- /dev/null +++ b/test/Modules/self-import-header/af.framework/Headers/a2.h @@ -0,0 +1 @@ +#import "a1.h" diff --git a/test/Modules/self-import-header/af.framework/module.map b/test/Modules/self-import-header/af.framework/module.map new file mode 100644 index 0000000..8717683 --- /dev/null +++ b/test/Modules/self-import-header/af.framework/module.map @@ -0,0 +1,4 @@ +framework module af { + header "a1.h" + header "a2.h" +} diff --git a/test/Modules/self-import-header/depend_builtin/h1.h b/test/Modules/self-import-header/depend_builtin/h1.h new file mode 100644 index 0000000..13298ef --- /dev/null +++ b/test/Modules/self-import-header/depend_builtin/h1.h @@ -0,0 +1 @@ +#include <float.h> diff --git a/test/Modules/self-import-header/depend_builtin/module.map b/test/Modules/self-import-header/depend_builtin/module.map new file mode 100644 index 0000000..a736ad8 --- /dev/null +++ b/test/Modules/self-import-header/depend_builtin/module.map @@ -0,0 +1,5 @@ +module DepBuiltin { +header "h1.h" + export * +} + diff --git a/test/Modules/self-import-header/test.m b/test/Modules/self-import-header/test.m new file mode 100644 index 0000000..377c01d --- /dev/null +++ b/test/Modules/self-import-header/test.m @@ -0,0 +1,8 @@ +// rdar://13840148 + +// RUN: rm -rf %t +// RUN: %clang -fsyntax-only -isysroot %S/../Inputs/System/usr/include -fmodules -fmodules-cache-path=%t \ +// RUN: -target x86_64-darwin \ +// RUN: -F %S -I %S %s -D__need_wint_t -Werror=implicit-function-declaration + +@import af; diff --git a/test/Modules/separate_map_tree.cpp b/test/Modules/separate_map_tree.cpp new file mode 100644 index 0000000..5a1fff4 --- /dev/null +++ b/test/Modules/separate_map_tree.cpp @@ -0,0 +1,8 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fmodules-decluse -fmodule-name=A -fmodule-map-file=%S/Inputs/separate_map_tree/maps/modulea.map -I %S/Inputs/separate_map_tree/src %s -verify + +#include "common.h" +#include "public-in-b.h" // expected-error {{private header}} +#include "public-in-c.h" +#include "private-in-c.h" // expected-error {{private header}} +const int val = common + b + c + c_; // expected-error {{undeclared identifier}} diff --git a/test/Modules/subframeworks.m b/test/Modules/subframeworks.m index ad70cc2..5d70bc0 100644 --- a/test/Modules/subframeworks.m +++ b/test/Modules/subframeworks.m @@ -5,7 +5,8 @@ @import DependsOnModule; void testSubFramework() { - float *sf1 = sub_framework; // expected-error{{use of undeclared identifier 'sub_framework'}} + float *sf1 = sub_framework; // expected-error{{declaration of 'sub_framework' must be imported from module 'DependsOnModule.SubFramework' before it is required}} + // expected-note@Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h:2 {{previous}} } @import DependsOnModule.SubFramework; diff --git a/test/Modules/submodules.cpp b/test/Modules/submodules.cpp index 1b4f5d8..9c62389 100644 --- a/test/Modules/submodules.cpp +++ b/test/Modules/submodules.cpp @@ -7,8 +7,9 @@ vector<int> vi; // Note: remove_reference is not visible yet. -remove_reference<int&>::type *int_ptr = 0; // expected-error{{unknown type name 'remove_reference'}} \ -// expected-error{{expected unqualified-id}} +remove_reference<int&>::type *int_ptr = 0; // expected-error{{declaration of 'remove_reference' must be imported from module 'std.type_traits' before it is required}} +// expected-note@Inputs/submodules/type_traits.h:2{{previous}} +// expected-note@Inputs/submodules/hash_map.h:1{{previous}} @import std.typetraits; // expected-error{{no submodule named 'typetraits' in module 'std'; did you mean 'type_traits'?}} @@ -20,10 +21,16 @@ remove_reference<int&>::type *int_ptr2 = 0; @import std; // import everything in 'std' // hash_map still isn't available. -hash_map<int, float> ints_to_floats; // expected-error{{unknown type name 'hash_map'}} \ -// expected-error{{expected unqualified-id}} +hash_map<int, float> ints_to_floats; // expected-error{{declaration of 'hash_map' must be imported from module 'std.hash_map' before it is required}} @import std.hash_map; hash_map<int, float> ints_to_floats2; +@import import_self.b; +extern MyTypeA import_self_test_a; // expected-error {{must be imported from module 'import_self.a'}} +// expected-note@import-self-a.h:1 {{here}} +extern MyTypeC import_self_test_c; +// FIXME: This should be valid; import_self.b re-exports import_self.d. +extern MyTypeD import_self_test_d; // expected-error {{must be imported from module 'import_self.d'}} +// expected-note@import-self-d.h:1 {{here}} diff --git a/test/Modules/system_headers.m b/test/Modules/system_headers.m new file mode 100644 index 0000000..39b13ca --- /dev/null +++ b/test/Modules/system_headers.m @@ -0,0 +1,8 @@ +// Test that system-headerness works for building modules. + +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache -isystem %S/Inputs -pedantic -Werror %s -verify +// expected-no-diagnostics + +@import warning; +int i = bigger_than_int; diff --git a/test/Modules/templates.mm b/test/Modules/templates.mm index 1fef967..080f9e7 100644 --- a/test/Modules/templates.mm +++ b/test/Modules/templates.mm @@ -1,11 +1,15 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs -verify %s -Wno-objc-root-class -// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs -emit-llvm %s -o - -Wno-objc-root-class | grep Emit | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs -verify %s -Wno-objc-root-class +// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs -emit-llvm %s -o - -Wno-objc-root-class | FileCheck %s // expected-no-diagnostics @import templates_left; @import templates_right; +// CHECK: @list_left = global { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 8, +// CHECK: @list_right = global { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 12, +// CHECK: @_ZZ15testMixedStructvE1l = {{.*}} constant { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 1, +// CHECK: @_ZZ15testMixedStructvE1r = {{.*}} constant { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 2, void testTemplateClasses() { Vector<int> vec_int; @@ -32,5 +36,34 @@ void testRedeclDefinition() { redeclDefinitionEmit(); } +// These three are all the same type. +typedef OuterIntInner_left OuterIntInner; +typedef OuterIntInner_right OuterIntInner; +typedef Outer<int>::Inner OuterIntInner; + // CHECK: call {{.*pendingInstantiation}} // CHECK: call {{.*redeclDefinitionEmit}} + +static_assert(size_left == size_right, "same field both ways"); +void useListInt(List<int> &); + +// CHECK-LABEL: define i32 @_Z15testMixedStructv( +unsigned testMixedStruct() { + // CHECK: %[[l:.*]] = alloca %[[ListInt:[^ ]*]], align 8 + // CHECK: %[[r:.*]] = alloca %[[ListInt]], align 8 + + // CHECK: call {{.*}}memcpy{{.*}}(i8* %{{.*}}, i8* bitcast ({{.*}}* @_ZZ15testMixedStructvE1l to i8*), i64 16, + ListInt_left l{0, 1}; + + // CHECK: call {{.*}}memcpy{{.*}}(i8* %{{.*}}, i8* bitcast ({{.*}}* @_ZZ15testMixedStructvE1r to i8*), i64 16, + ListInt_right r{0, 2}; + + // CHECK: call void @_Z10useListIntR4ListIiE(%[[ListInt]]* %[[l]]) + useListInt(l); + // CHECK: call void @_Z10useListIntR4ListIiE(%[[ListInt]]* %[[r]]) + useListInt(r); + + // CHECK: load i32* bitcast (i8* getelementptr inbounds (i8* bitcast ({{.*}}* @list_left to i8*), i64 8) to i32*) + // CHECK: load i32* bitcast (i8* getelementptr inbounds (i8* bitcast ({{.*}}* @list_right to i8*), i64 8) to i32*) + return list_left.*size_right + list_right.*size_left; +} diff --git a/test/Modules/using-decl.cpp b/test/Modules/using-decl.cpp new file mode 100644 index 0000000..4432738 --- /dev/null +++ b/test/Modules/using-decl.cpp @@ -0,0 +1,8 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify + +@import using_decl.a; + +// expected-no-diagnostics +UsingDecl::using_decl_type x = UsingDecl::using_decl_var; +UsingDecl::inner y = x; |