1 // RUN: split-file %s %t 2 3 // RUN: %clang_cc1 -std=c++14 -x c++ -fmodules -fmodule-name=A -emit-module %t/a.modulemap -o %t/a.pcm 4 // RUN: %clang_cc1 -std=c++14 -x c++ -fmodules -fmodule-name=B -emit-module %t/b.modulemap -o %t/b.pcm 5 // RUN: %clang_cc1 -std=c++14 -x c++ -fmodules -fmodule-map-file=%t/a.modulemap -fmodule-map-file=%t/b.modulemap \ 6 // RUN: -fmodule-file=%t/a.pcm -fmodule-file=%t/b.pcm \ 7 // RUN: %t/use.cc -verify 8 9 // RUN: rm -f %t/*.pcm 10 11 // RUN: %clang_cc1 -std=c++14 -x c++ -fmodules -fmodule-name=A -emit-module %t/a.modulemap -o %t/a.pcm -triple i686-windows 12 // RUN: %clang_cc1 -std=c++14 -x c++ -fmodules -fmodule-name=B -emit-module %t/b.modulemap -o %t/b.pcm -triple i686-windows 13 // RUN: %clang_cc1 -std=c++14 -x c++ -fmodules -fmodule-map-file=%t/a.modulemap -fmodule-map-file=%t/b.modulemap \ 14 // RUN: -fmodule-file=%t/a.pcm -fmodule-file=%t/b.pcm \ 15 // RUN: %t/use.cc -verify -triple i686-windows 16 17 //--- a.modulemap 18 module A { 19 header "a.h" 20 } 21 22 //--- a.h 23 #ifndef A_H 24 #define A_H 25 template<typename T> struct ct { friend auto operator-(ct, ct) { struct X {}; return X(); } void x(); }; 26 #endif 27 28 //--- b.modulemap 29 module B { 30 header "b.h" 31 } 32 33 //--- b.h 34 #ifndef B_H 35 #define B_H 36 template<typename T> struct ct { friend auto operator-(ct, ct) { struct X {}; return X(); } void x(); }; 37 inline auto f() { return ct<float>() - ct<float>(); } 38 #endif 39 40 //--- use.cc 41 // expected-no-diagnostics 42 // Force the definition of ct in module A to be the primary definition. 43 #include "a.h" 44 template<typename T> void ct<T>::x() {} 45 46 // Attempt to cause the definition of operator- in the ct primary template in 47 // module B to be the primary definition of that function. If that happens, 48 // we'll be left with a class template ct that appears to not contain a 49 // definition of the inline friend function. 50 #include "b.h" 51 auto v = f(); 52 53 ct<int> make(); 54 void h() { 55 make() - make(); 56 } 57