1 // Based on C++20 10.2 example 5. 2 3 // RUN: rm -rf %t 4 // RUN: mkdir -p %t 5 // RUN: split-file %s %t 6 7 // RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/std-10-2-ex5-tu1.cpp \ 8 // RUN: -o %t/M.pcm 9 10 // RUN: %clang_cc1 -std=c++20 -emit-obj %t/std-10-2-ex5-tu2.cpp \ 11 // RUN: -fmodule-file=M=%t/M.pcm -o %t/tu-2.o 12 13 // RUN: %clang_cc1 -std=c++20 -emit-obj %t/std-10-2-ex5-tu3.cpp \ 14 // RUN: -fmodule-file=M=%t/M.pcm -verify -o %t/main.o 15 16 // Test again with reduced BMI. 17 // RUN: rm %t/M.pcm 18 // RUN: %clang_cc1 -std=c++20 -emit-reduced-module-interface %t/std-10-2-ex5-tu1.cpp \ 19 // RUN: -o %t/M.pcm 20 21 // RUN: %clang_cc1 -std=c++20 -emit-obj %t/std-10-2-ex5-tu2.cpp \ 22 // RUN: -fmodule-file=M=%t/M.pcm -o %t/tu-2.o 23 24 // RUN: %clang_cc1 -std=c++20 -emit-obj %t/std-10-2-ex5-tu3.cpp \ 25 // RUN: -fmodule-file=M=%t/M.pcm -verify -o %t/main.o 26 27 28 //--- std-10-2-ex5-tu1.cpp 29 export module M; 30 export struct X { 31 static void f(); 32 struct Y {}; 33 }; 34 namespace { 35 struct S {}; 36 } // namespace 37 export void f(S); // OK 38 struct T {}; 39 export T id(T); // OK 40 export struct A; // A exported as incomplete 41 rootFinder(double a)42export auto rootFinder(double a) { 43 return [=](double x) { return (x + a / x) / 2; }; 44 } 45 export const int n = 5; // OK, n has external linkage 46 47 //--- std-10-2-ex5-tu2.cpp 48 49 module M; 50 struct A { 51 int value; 52 }; 53 54 //--- std-10-2-ex5-tu3.cpp 55 56 import M; 57 main()58int main() { 59 X::f(); // OK, X is exported and definition of X is reachable 60 X::Y y; // OK, X::Y is exported as a complete type 61 auto f = rootFinder(2); // OK 62 // error: A is incomplete 63 return A{45}.value; // expected-error {{invalid use of incomplete type 'A'}} 64 // expected-error@-1 {{member access into incomplete type 'A'}} 65 // expected-note@std-10-2-ex5-tu1.cpp:12 2{{forward declaration of 'A'}} 66 } 67