Home | History | Annotate | Download | only in SemaTemplate
      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 
     29 void test(const Streamer<Foo>& foo)
     30 {
     31     cout << foo;
     32 }
     33 
     34 template <typename STRUCT_TYPE>
     35 struct Streamer
     36 {
     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 
     44     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
     59 std_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 <>
     67 void Streamer<Foo>::operator () (std_ostream& o) const // expected-note{{requested here}}
     68 {
     69 }
     70 #endif
     71 
     72 int main(void)
     73 {
     74     Foo foo;
     75     test(foo);
     76 }
     77 
     78