1*67e74705SXin Li // RUN: %clang_cc1 %s -std=c++98 -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s 2*67e74705SXin Li // RUN: %clang_cc1 %s -std=c++98 -triple %itanium_abi_triple -emit-llvm -o - -DPROTOTYPE | FileCheck --check-prefix=CHECK-PROTOTYPE %s 3*67e74705SXin Li // RUN: %clang_cc1 %s -std=c++98 -triple %itanium_abi_triple -emit-llvm -o - -DINSTANTIATE | FileCheck --check-prefix=CHECK-INSTANTIATE %s 4*67e74705SXin Li // RUN: %clang_cc1 %s -std=c++98 -triple %itanium_abi_triple -emit-llvm -o - -DPROTOTYPE -DINSTANTIATE | FileCheck --check-prefix=CHECK-PROTOTYPE-INSTANTIATE %s 5*67e74705SXin Li // RUN: %clang_cc1 %s -DREDEFINE -verify 6*67e74705SXin Li // RUN: %clang_cc1 %s -DPROTOTYPE -DREDEFINE -verify 7*67e74705SXin Li // PR8007: friend function not instantiated, reordered version. 8*67e74705SXin Li // Corresponds to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38392 9*67e74705SXin Li 10*67e74705SXin Li // CHECK: define linkonce_odr{{.*}}_ZlsR11std_ostreamRK8StreamerI3FooE 11*67e74705SXin Li // CHECK-PROTOTYPE: define linkonce_odr{{.*}}_ZlsR11std_ostreamRK8StreamerI3FooE 12*67e74705SXin Li // CHECK-INSTANTIATE: define linkonce_odr{{.*}}_ZlsR11std_ostreamRK8StreamerI3FooE 13*67e74705SXin Li // CHECK-PROTOTYPE-INSTANTIATE: define linkonce_odr{{.*}}_ZlsR11std_ostreamRK8StreamerI3FooE 14*67e74705SXin Li 15*67e74705SXin Li struct std_ostream 16*67e74705SXin Li { 17*67e74705SXin Li int dummy; 18*67e74705SXin Li }; 19*67e74705SXin Li 20*67e74705SXin Li std_ostream cout; 21*67e74705SXin Li 22*67e74705SXin Li template <typename STRUCT_TYPE> 23*67e74705SXin Li struct Streamer; 24*67e74705SXin Li 25*67e74705SXin Li typedef struct Foo {} Foo; 26*67e74705SXin Li 27*67e74705SXin Li inline std_ostream& operator << (std_ostream&, const Streamer<Foo>&); 28*67e74705SXin Li test(const Streamer<Foo> & foo)29*67e74705SXin Livoid test(const Streamer<Foo>& foo) 30*67e74705SXin Li { 31*67e74705SXin Li cout << foo; 32*67e74705SXin Li } 33*67e74705SXin Li 34*67e74705SXin Li template <typename STRUCT_TYPE> 35*67e74705SXin Li struct Streamer 36*67e74705SXin Li { operator <<(std_ostream & o,const Streamer & f)37*67e74705SXin Li friend std_ostream& operator << (std_ostream& o, const Streamer& f) // expected-error{{redefinition of 'operator<<'}} 38*67e74705SXin Li { 39*67e74705SXin Li Streamer s(f); 40*67e74705SXin Li s(o); 41*67e74705SXin Li return o; 42*67e74705SXin Li } 43*67e74705SXin Li StreamerStreamer44*67e74705SXin Li Streamer(const STRUCT_TYPE& s) : s(s) {} 45*67e74705SXin Li 46*67e74705SXin Li const STRUCT_TYPE& s; 47*67e74705SXin Li void operator () (std_ostream&) const; 48*67e74705SXin Li }; 49*67e74705SXin Li 50*67e74705SXin Li #ifdef PROTOTYPE 51*67e74705SXin Li std_ostream& operator << (std_ostream&, const Streamer<Foo>&); 52*67e74705SXin Li #endif 53*67e74705SXin Li 54*67e74705SXin Li #ifdef INSTANTIATE 55*67e74705SXin Li template struct Streamer<Foo>; 56*67e74705SXin Li #endif 57*67e74705SXin Li 58*67e74705SXin Li #ifdef REDEFINE operator <<(std_ostream & o,const Streamer<Foo> &)59*67e74705SXin Listd_ostream& operator << (std_ostream& o, const Streamer<Foo>&) // expected-note{{is here}} 60*67e74705SXin Li { 61*67e74705SXin Li return o; 62*67e74705SXin Li } 63*67e74705SXin Li #endif 64*67e74705SXin Li 65*67e74705SXin Li #ifndef INSTANTIATE 66*67e74705SXin Li template <> operator ()(std_ostream & o) const67*67e74705SXin Livoid Streamer<Foo>::operator () (std_ostream& o) const // expected-note{{requested here}} 68*67e74705SXin Li { 69*67e74705SXin Li } 70*67e74705SXin Li #endif 71*67e74705SXin Li main(void)72*67e74705SXin Liint main(void) 73*67e74705SXin Li { 74*67e74705SXin Li Foo foo; 75*67e74705SXin Li test(foo); 76*67e74705SXin Li } 77*67e74705SXin Li 78