diff options
Diffstat (limited to 'test/CXX/module')
-rw-r--r-- | test/CXX/module/module.interface/Inputs/header.h | 3 | ||||
-rw-r--r-- | test/CXX/module/module.interface/p1.cpp | 38 | ||||
-rw-r--r-- | test/CXX/module/module.interface/p2.cpp | 94 | ||||
-rw-r--r-- | test/CXX/module/module.interface/p3.cpp | 54 | ||||
-rw-r--r-- | test/CXX/module/module.interface/p5.cpp | 89 | ||||
-rw-r--r-- | test/CXX/module/module.unit/p3.cpp | 4 | ||||
-rw-r--r-- | test/CXX/module/module.unit/p8.cpp | 40 |
7 files changed, 322 insertions, 0 deletions
diff --git a/test/CXX/module/module.interface/Inputs/header.h b/test/CXX/module/module.interface/Inputs/header.h new file mode 100644 index 0000000000..f2e2cbb53c --- /dev/null +++ b/test/CXX/module/module.interface/Inputs/header.h @@ -0,0 +1,3 @@ +extern int foo; +namespace bar { extern int baz(); } +static int baz; diff --git a/test/CXX/module/module.interface/p1.cpp b/test/CXX/module/module.interface/p1.cpp new file mode 100644 index 0000000000..0947b81915 --- /dev/null +++ b/test/CXX/module/module.interface/p1.cpp @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -std=c++2a %s -DERRORS -verify +// RUN: %clang_cc1 -std=c++2a %s -emit-module-interface -o %t.pcm +// RUN: %clang_cc1 -std=c++2a %s -fmodule-file=%t.pcm -DIMPLEMENTATION -verify -Db=b2 -Dc=c2 + +module; + +#ifdef ERRORS +export int a; // expected-error {{after the module declaration}} +#endif + +#ifndef IMPLEMENTATION +export +#else +// expected-error@#1 {{can only be used within a module interface unit}} +// expected-error@#2 {{can only be used within a module interface unit}} +// expected-note@+2 1+{{add 'export'}} +#endif +module M; + +export int b; // #1 +namespace N { + export int c; // #2 +} + +#ifdef ERRORS +namespace { // expected-note 2{{anonymous namespace begins here}} + export int d1; // expected-error {{export declaration appears within anonymous namespace}} + namespace X { + export int d2; // expected-error {{export declaration appears within anonymous namespace}} + } +} + +export export int e; // expected-error {{within another export declaration}} +export { export int f; } // expected-error {{within another export declaration}} expected-note {{export block begins here}} + +module :private; // expected-note {{private module fragment begins here}} +export int priv; // expected-error {{export declaration cannot be used in a private module fragment}} +#endif diff --git a/test/CXX/module/module.interface/p2.cpp b/test/CXX/module/module.interface/p2.cpp new file mode 100644 index 0000000000..0a6f8c2aad --- /dev/null +++ b/test/CXX/module/module.interface/p2.cpp @@ -0,0 +1,94 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: %clang_cc1 -std=c++2a -x c++-header %S/Inputs/header.h -emit-header-module -fmodule-name=FIXME -o %t/h.pcm +// RUN: %clang_cc1 -std=c++2a %s -DX_INTERFACE -emit-module-interface -o %t/x.pcm +// RUN: %clang_cc1 -std=c++2a %s -DY_INTERFACE -emit-module-interface -o %t/y.pcm +// RUN: %clang_cc1 -std=c++2a %s -DINTERFACE -fmodule-file=%t/x.pcm -fmodule-file=%t/y.pcm -emit-module-interface -o %t/m.pcm +// RUN: %clang_cc1 -std=c++2a %s -DIMPLEMENTATION -I%S/Inputs -fmodule-file=%t/h.pcm -fmodule-file=%t/m.pcm -verify +// RUN: %clang_cc1 -std=c++2a %s -DUSER -I%S/Inputs -fmodule-file=%t/h.pcm -fmodule-file=%t/m.pcm -verify + +#if defined(X_INTERFACE) +export module X; +export int x; + +#elif defined(Y_INTERFACE) +export module Y; +export int y; + +#elif defined(INTERFACE) +export module p2; +export import X; +import Y; // not exported + +namespace A { + int f(); + export int g(); + int h(); + namespace inner {} +} +export namespace B { + namespace inner {} +} +namespace B { + int f(); +} +namespace C {} +namespace D { int f(); } +export namespace D {} + +#elif defined(IMPLEMENTATION) +module p2; +import "header.h"; + +// Per [basic.scope.namespace]/2.3, exportedness has no impact on visibility +// within the same module. +// +// expected-no-diagnostics + +void use() { + A::f(); + A::g(); + A::h(); + using namespace A::inner; + + using namespace B; + using namespace B::inner; + B::f(); + f(); + + using namespace C; + + D::f(); +} + +int use_header() { return foo + bar::baz(); } + +#elif defined(USER) +import p2; +import "header.h"; + +void use() { + // namespace A is implicitly exported by the export of A::g. + A::f(); // expected-error {{no member named 'f' in namespace 'A'}} + A::g(); + A::h(); // expected-error {{no member named 'h' in namespace 'A'}} + using namespace A::inner; // expected-error {{expected namespace name}} + + // namespace B and B::inner are explicitly exported + using namespace B; + using namespace B::inner; + B::f(); // expected-error {{no member named 'f' in namespace 'B'}} + f(); // expected-error {{undeclared identifier 'f'}} + + // namespace C is not exported + using namespace C; // expected-error {{expected namespace name}} + + // namespace D is exported, but D::f is not + D::f(); // expected-error {{no member named 'f' in namespace 'D'}} +} + +int use_header() { return foo + bar::baz(); } + +#else +#error unknown mode +#endif diff --git a/test/CXX/module/module.interface/p3.cpp b/test/CXX/module/module.interface/p3.cpp new file mode 100644 index 0000000000..29d2cb43b4 --- /dev/null +++ b/test/CXX/module/module.interface/p3.cpp @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -std=c++2a %s -verify -pedantic-errors + +export module p3; + +namespace A { int ns_mem; } + +// An exported declaration shall declare at least one name. +export; // expected-error {{empty declaration cannot be exported}} +export static_assert(true); // expected-error {{static_assert declaration cannot be exported}} +export using namespace A; // expected-error {{ISO C++20 does not permit using directive to be exported}} + +export { // expected-note 3{{export block begins here}} + ; // expected-error {{ISO C++20 does not permit an empty declaration to appear in an export block}} + static_assert(true); // expected-error {{ISO C++20 does not permit a static_assert declaration to appear in an export block}} + using namespace A; // expected-error {{ISO C++20 does not permit using directive to be exported}} +} + +export struct {}; // expected-error {{must be class member}} expected-error {{GNU extension}} expected-error {{does not declare anything}} +export struct {} struct_; +export union {}; // expected-error {{must be declared 'static'}} expected-error {{does not declare anything}} +export union {} union_; +export enum {}; // expected-error {{does not declare anything}} +export enum {} enum_; +export enum E : int; +export typedef int; // expected-error {{typedef requires a name}} +export static union {}; // expected-error {{does not declare anything}} +export asm(""); // expected-error {{asm declaration cannot be exported}} +export namespace B = A; +export using A::ns_mem; +namespace A { + export using A::ns_mem; +} +export using Int = int; +export extern "C++" {} // expected-error {{ISO C++20 does not permit a declaration that does not introduce any names to be exported}} +export extern "C++" { extern "C" {} } // expected-error {{ISO C++20 does not permit a declaration that does not introduce any names to be exported}} +export extern "C++" { extern "C" int extern_c; } +export { // expected-note {{export block}} + extern "C++" int extern_cxx; + extern "C++" {} // expected-error {{ISO C++20 does not permit a declaration that does not introduce any names to be exported}} +} +export [[]]; // FIXME (bad diagnostic text): expected-error {{empty declaration cannot be exported}} +export [[example::attr]]; // FIXME: expected-error {{empty declaration cannot be exported}} expected-warning {{unknown attribute 'attr'}} + +// [...] shall not declare a name with internal linkage +export static int a; // expected-error {{declaration of 'a' with internal linkage cannot be exported}} +export static int b(); // expected-error {{declaration of 'b' with internal linkage cannot be exported}} +export namespace { int c; } // expected-error {{declaration of 'c' with internal linkage cannot be exported}} +namespace { // expected-note {{here}} + export int d; // expected-error {{export declaration appears within anonymous namespace}} +} +export template<typename> static int e; // expected-error {{declaration of 'e' with internal linkage cannot be exported}} +export template<typename> static int f(); // expected-error {{declaration of 'f' with internal linkage cannot be exported}} +export const int k = 5; +export static union { int n; }; // expected-error {{declaration of 'n' with internal linkage cannot be exported}} diff --git a/test/CXX/module/module.interface/p5.cpp b/test/CXX/module/module.interface/p5.cpp new file mode 100644 index 0000000000..17c4105baa --- /dev/null +++ b/test/CXX/module/module.interface/p5.cpp @@ -0,0 +1,89 @@ +// RUN: %clang_cc1 -std=c++2a %s -verify -pedantic-errors + +export module p5; + +int a; +static int sa; // expected-note {{target}} +void b(); +static void sb(); // expected-note {{target}} +struct c {}; +enum d {}; +using e = int; +using f = c; +static union { int sg1, sg2; }; // expected-note {{target}} +namespace NS {} + +template<typename> int ta; +template<typename> static int sta; // expected-note {{target}} +template<typename> void tb(); +template<typename> static void stb(); // expected-note {{target}} +template<typename> struct tc {}; +template<typename> using te = int; +template<typename> using tf = c; + +namespace UnnamedNS { + namespace { + int a; // expected-note {{target}} + static int sa; // expected-note {{target}} + void b(); // expected-note {{target}} + static void sb(); // expected-note {{target}} + struct c {}; // expected-note {{target}} + enum d {}; // expected-note {{target}} + using e = int; + using f = c; + static union { int sg1, sg2; }; // expected-note {{target}} + namespace NS {} + + template<typename> int ta; // expected-note {{target}} + template<typename> static int sta; // expected-note {{target}} + template<typename> void tb(); // expected-note {{target}} + template<typename> static void stb(); // expected-note {{target}} + template<typename> struct tc {}; // expected-note {{target}} + template<typename> using te = int; // expected-note {{target}} + template<typename> using tf = c; // expected-note {{target}} + } +} + +export { // expected-note 19{{here}} + using ::a; + using ::sa; // expected-error {{using declaration referring to 'sa' with internal linkage}} + using ::b; + using ::sb; // expected-error {{using declaration referring to 'sb' with internal linkage}} + using ::c; + using ::d; + using ::e; + using ::f; + using ::sg1; // expected-error {{using declaration referring to 'sg1' with internal linkage}} + + using ::ta; + using ::sta; // expected-error {{using declaration referring to 'sta' with internal linkage}} + using ::tb; + using ::stb; // expected-error {{using declaration referring to 'stb' with internal linkage}} + using ::tc; + using ::te; + using ::tf; + namespace NS2 = ::NS; + + namespace UnnamedNS { + using UnnamedNS::a; // expected-error {{internal linkage}} + using UnnamedNS::sa; // expected-error {{internal linkage}} + using UnnamedNS::b; // expected-error {{internal linkage}} + using UnnamedNS::sb; // expected-error {{internal linkage}} + using UnnamedNS::c; // expected-error {{internal linkage}} + using UnnamedNS::d; // expected-error {{internal linkage}} + using UnnamedNS::e; // ok + using UnnamedNS::f; // ok? using-declaration refers to alias-declaration, + // which does not have linkage (even though that then + // refers to a type that has internal linkage) + using UnnamedNS::sg1; // expected-error {{internal linkage}} + + using UnnamedNS::ta; // expected-error {{internal linkage}} + using UnnamedNS::sta; // expected-error {{internal linkage}} + using UnnamedNS::tb; // expected-error {{internal linkage}} + using UnnamedNS::stb; // expected-error {{internal linkage}} + using UnnamedNS::tc; // expected-error {{internal linkage}} + using UnnamedNS::te; // expected-error {{internal linkage}} + using UnnamedNS::tf; // expected-error {{internal linkage}} + namespace NS2 = UnnamedNS::NS; // ok (wording bug?) + } +} diff --git a/test/CXX/module/module.unit/p3.cpp b/test/CXX/module/module.unit/p3.cpp new file mode 100644 index 0000000000..2e08f4a9a8 --- /dev/null +++ b/test/CXX/module/module.unit/p3.cpp @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -std=c++2a -verify %s + +export module foo:bar; // expected-error {{sorry, module partitions are not yet supported}} +import :baz; // expected-error {{sorry, module partitions are not yet supported}} diff --git a/test/CXX/module/module.unit/p8.cpp b/test/CXX/module/module.unit/p8.cpp new file mode 100644 index 0000000000..aad65272f0 --- /dev/null +++ b/test/CXX/module/module.unit/p8.cpp @@ -0,0 +1,40 @@ +// RUN: echo 'export module foo; export int n;' > %t.cppm +// RUN: %clang_cc1 -std=c++2a %t.cppm -emit-module-interface -o %t.pcm +// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=0 %s +// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=1 %s +// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=2 %s +// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=3 %s +// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=4 %s +// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=5 %s + +#if MODE == 0 +// no module declaration + +#elif MODE == 1 +// expected-no-diagnostics +module foo; +#define IMPORTED + +#elif MODE == 2 +export module foo; // expected-error {{redefinition of module 'foo'}} +// expected-note-re@* {{module loaded from '{{.*}}.pcm'}} +#define IMPORTED + +#elif MODE == 3 +export module bar; + +#elif MODE == 4 +module foo:bar; // expected-error {{not yet supported}} +#define IMPORTED // FIXME + +#elif MODE == 5 +export module foo:bar; // expected-error {{not yet supported}} expected-error {{redefinition}} expected-note@* {{loaded from}} +#define IMPORTED // FIXME + +#endif + +int k = n; +#ifndef IMPORTED +// expected-error@-2 {{declaration of 'n' must be imported from module 'foo' before it is required}} +// expected-note@* {{previous}} +#endif |