xref: /llvm-project/clang/test/CXX/module/module.interface/p7.cpp (revision c5e4afe6733c58e24023ede04275bbed3bde8240)
19c04851cSChuanqi Xu // RUN: rm -rf %t
29c04851cSChuanqi Xu // RUN: mkdir -p %t
39c04851cSChuanqi Xu // RUN: split-file %s %t
49c04851cSChuanqi Xu //
59c04851cSChuanqi Xu // RUN: %clang_cc1 -std=c++20 %t/p7.cppm -emit-module-interface -o %t/p7.pcm
69c04851cSChuanqi Xu // RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/Use.cpp -verify
79c04851cSChuanqi Xu 
89c04851cSChuanqi Xu //--- p7.cppm
99c04851cSChuanqi Xu export module p7;
109c04851cSChuanqi Xu struct reachable {
119c04851cSChuanqi Xu   constexpr static int sv = 43;
129c04851cSChuanqi Xu   int value = 44;
139c04851cSChuanqi Xu 
149c04851cSChuanqi Xu   static int getValue() { return 43; }
159c04851cSChuanqi Xu   int get() { return 44; }
169c04851cSChuanqi Xu 
179c04851cSChuanqi Xu   template <typename T>
189c04851cSChuanqi Xu   static bool templ_get(T t) { return false; }
199c04851cSChuanqi Xu   typedef int typedef_type;
209c04851cSChuanqi Xu   using using_type = int;
219c04851cSChuanqi Xu   template <typename T>
229c04851cSChuanqi Xu   using templ_using_type = int;
239c04851cSChuanqi Xu   bool operator()() {
249c04851cSChuanqi Xu     return false;
259c04851cSChuanqi Xu   }
269c04851cSChuanqi Xu 
279c04851cSChuanqi Xu   enum E { a,
289c04851cSChuanqi Xu            b };
299c04851cSChuanqi Xu };
309c04851cSChuanqi Xu 
319c04851cSChuanqi Xu export auto getReachable() {
329c04851cSChuanqi Xu   return reachable{};
339c04851cSChuanqi Xu }
349c04851cSChuanqi Xu 
359c04851cSChuanqi Xu export enum E1 { e1 };
369c04851cSChuanqi Xu enum E2 { e2 };
379c04851cSChuanqi Xu export using E2U = E2;
389c04851cSChuanqi Xu enum E3 { e3 };
399c04851cSChuanqi Xu export E3 func();
409c04851cSChuanqi Xu 
419c04851cSChuanqi Xu //--- Use.cpp
429c04851cSChuanqi Xu import p7;
439c04851cSChuanqi Xu void test() {
449c04851cSChuanqi Xu   auto reachable = getReachable();
459c04851cSChuanqi Xu   int a = decltype(reachable)::sv;
469c04851cSChuanqi Xu   int b = decltype(reachable)::getValue();
479c04851cSChuanqi Xu   int c = reachable.value;
489c04851cSChuanqi Xu   int d = reachable.get();
499c04851cSChuanqi Xu   int e = decltype(reachable)::a;
509c04851cSChuanqi Xu   int f = reachable.templ_get(a);
519c04851cSChuanqi Xu   typename decltype(reachable)::typedef_type g;
529c04851cSChuanqi Xu   typename decltype(reachable)::using_type h;
539c04851cSChuanqi Xu   typename decltype(reachable)::template templ_using_type<int> j;
549c04851cSChuanqi Xu   auto value = reachable();
559c04851cSChuanqi Xu }
569c04851cSChuanqi Xu 
579c04851cSChuanqi Xu void test2() {
589c04851cSChuanqi Xu   auto a = E1::e1;               // OK, namespace-scope name E1 is visible and e1 is reachable
599c04851cSChuanqi Xu   auto b = e1;                   // OK, namespace-scope name e1 is visible
60*c5e4afe6SChuanqi Xu   auto c = E2::e2;               // expected-error {{use of undeclared identifier 'E2'}}
61*c5e4afe6SChuanqi Xu   auto d = e2;                   // expected-error {{use of undeclared identifier 'e2'}}
629c04851cSChuanqi Xu   auto e = E2U::e2;              // OK, namespace-scope name E2U is visible and E2::e2 is reachable
63*c5e4afe6SChuanqi Xu   auto f = E3::e3;               // expected-error {{use of undeclared identifier 'E3'}}
64*c5e4afe6SChuanqi Xu   auto g = e3;                   // expected-error {{use of undeclared identifier 'e3'}}
659c04851cSChuanqi Xu   auto h = decltype(func())::e3; // OK, namespace-scope name f is visible and E3::e3 is reachable
669c04851cSChuanqi Xu }
67