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