xref: /llvm-project/clang/test/CXX/module/module.interface/p2.cpp (revision db3d0e4dfa34e59fab90c0726a6722f82db48462)
1e181de7fSRichard Smith // RUN: rm -rf %t
2e181de7fSRichard Smith // RUN: mkdir -p %t
34a7be42dSChuanqi Xu // RUN: %clang_cc1 -std=c++20 -x c++-header %S/Inputs/header.h -emit-header-unit -o %t/h.pcm
44a7be42dSChuanqi Xu // RUN: %clang_cc1 -std=c++20 %s -DX_INTERFACE -emit-module-interface -o %t/x.pcm
54a7be42dSChuanqi Xu // RUN: %clang_cc1 -std=c++20 %s -DY_INTERFACE -emit-module-interface -o %t/y.pcm
657833636SChuanqi Xu // RUN: %clang_cc1 -std=c++20 %s -DINTERFACE -fmodule-file=X=%t/x.pcm -fmodule-file=Y=%t/y.pcm -emit-module-interface -o %t/m.pcm
7e22fa1d4SChuanqi Xu // RUN: %clang_cc1 -std=c++20 %s -DIMPLEMENTATION -I%S/Inputs -fmodule-file=%t/h.pcm \
8*fc89e904SChuanqi Xu // RUN:   -fmodule-file=X=%t/x.pcm -fmodule-file=Y=%t/y.pcm -fmodule-file=p2=%t/m.pcm -verify \
9*fc89e904SChuanqi Xu // RUN:   -Wno-experimental-header-units
10e22fa1d4SChuanqi Xu // RUN: %clang_cc1 -std=c++20 %s -DUSER -I%S/Inputs -fmodule-file=%t/h.pcm -fmodule-file=p2=%t/m.pcm \
11*fc89e904SChuanqi Xu // RUN:   -fmodule-file=X=%t/x.pcm -fmodule-file=Y=%t/y.pcm -Wno-experimental-header-units -verify
12e181de7fSRichard Smith 
13e181de7fSRichard Smith #if defined(X_INTERFACE)
14e181de7fSRichard Smith export module X;
15e181de7fSRichard Smith export int x;
16e181de7fSRichard Smith 
17e181de7fSRichard Smith #elif defined(Y_INTERFACE)
18e181de7fSRichard Smith export module Y;
19e181de7fSRichard Smith export int y;
20e181de7fSRichard Smith 
21e181de7fSRichard Smith #elif defined(INTERFACE)
22e181de7fSRichard Smith export module p2;
23e181de7fSRichard Smith export import X;
24e181de7fSRichard Smith import Y; // not exported
25e181de7fSRichard Smith 
26e181de7fSRichard Smith namespace A {
27e181de7fSRichard Smith   int f();
28e181de7fSRichard Smith   export int g();
29e181de7fSRichard Smith   int h();
30e181de7fSRichard Smith   namespace inner {}
31e181de7fSRichard Smith }
32e181de7fSRichard Smith export namespace B {
33e181de7fSRichard Smith   namespace inner {}
34e181de7fSRichard Smith }
35e181de7fSRichard Smith namespace B {
36e181de7fSRichard Smith   int f();
37e181de7fSRichard Smith }
38e181de7fSRichard Smith namespace C {}
39e181de7fSRichard Smith namespace D { int f(); }
40e181de7fSRichard Smith export namespace D {}
41e181de7fSRichard Smith 
42e181de7fSRichard Smith #elif defined(IMPLEMENTATION)
43e181de7fSRichard Smith module p2;
44e181de7fSRichard Smith import "header.h";
45e181de7fSRichard Smith 
46e181de7fSRichard Smith // Per [basic.scope.namespace]/2.3, exportedness has no impact on visibility
47e181de7fSRichard Smith // within the same module.
48e181de7fSRichard Smith //
49e181de7fSRichard Smith // expected-no-diagnostics
50e181de7fSRichard Smith 
use()51e181de7fSRichard Smith void use() {
52e181de7fSRichard Smith   A::f();
53e181de7fSRichard Smith   A::g();
54e181de7fSRichard Smith   A::h();
55e181de7fSRichard Smith   using namespace A::inner;
56e181de7fSRichard Smith 
57e181de7fSRichard Smith   using namespace B;
58e181de7fSRichard Smith   using namespace B::inner;
59e181de7fSRichard Smith   B::f();
60e181de7fSRichard Smith   f();
61e181de7fSRichard Smith 
62e181de7fSRichard Smith   using namespace C;
63e181de7fSRichard Smith 
64e181de7fSRichard Smith   D::f();
65e181de7fSRichard Smith }
66e181de7fSRichard Smith 
use_header()67e181de7fSRichard Smith int use_header() { return foo + bar::baz(); }
68e181de7fSRichard Smith 
69e181de7fSRichard Smith #elif defined(USER)
70e181de7fSRichard Smith import p2;
71e181de7fSRichard Smith import "header.h";
72e181de7fSRichard Smith 
use()73e181de7fSRichard Smith void use() {
74e181de7fSRichard Smith   // namespace A is implicitly exported by the export of A::g.
759c04851cSChuanqi Xu   A::f(); // expected-error {{declaration of 'f' must be imported from module 'p2' before it is required}}
769c04851cSChuanqi Xu           // expected-note@* {{declaration here is not visible}}
77e181de7fSRichard Smith   A::g();
789c04851cSChuanqi Xu   A::h();                   // expected-error {{declaration of 'h' must be imported from module 'p2' before it is required}}
799c04851cSChuanqi Xu                             // expected-note@* {{declaration here is not visible}}
809c04851cSChuanqi Xu   using namespace A::inner; // expected-error {{declaration of 'inner' must be imported from module 'p2' before it is required}}
81e181de7fSRichard Smith 
82e181de7fSRichard Smith   // namespace B and B::inner are explicitly exported
83e181de7fSRichard Smith   using namespace B;
84e181de7fSRichard Smith   using namespace B::inner;
859c04851cSChuanqi Xu   B::f(); // expected-error {{declaration of 'f' must be imported from module 'p2' before it is required}}
869c04851cSChuanqi Xu           // expected-note@* {{declaration here is not visible}}
879c04851cSChuanqi Xu   f();    // expected-error {{declaration of 'f' must be imported from module 'p2' before it is required}}
889c04851cSChuanqi Xu           // expected-note@* {{declaration here is not visible}}
89e181de7fSRichard Smith 
90e181de7fSRichard Smith   // namespace C is not exported
919c04851cSChuanqi Xu   using namespace C; // expected-error {{declaration of 'C' must be imported from module 'p2' before it is required}}
92e181de7fSRichard Smith 
93e181de7fSRichard Smith   // namespace D is exported, but D::f is not
949c04851cSChuanqi Xu   D::f(); // expected-error {{declaration of 'f' must be imported from module 'p2' before it is required}}
959c04851cSChuanqi Xu           // expected-note@* {{declaration here is not visible}}
96e181de7fSRichard Smith }
97e181de7fSRichard Smith 
use_header()98e181de7fSRichard Smith int use_header() { return foo + bar::baz(); }
99e181de7fSRichard Smith 
100e181de7fSRichard Smith #else
101e181de7fSRichard Smith #error unknown mode
102e181de7fSRichard Smith #endif
103