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