1 // RUN: %clang_cc1 -fsyntax-only -verify %s 2 3 namespace test0 { 4 template <class T> class A { 5 class Member {}; 6 }; 7 8 class B { 9 template <class T> friend class A<T>::Member; 10 }; 11 12 A<int> a; 13 B b; 14 } 15 16 // rdar://problem/8204127 17 namespace test1 { 18 template <class T> struct A; 19 20 class C { 21 static void foo(); 22 template <class T> friend void A<T>::f(); 23 }; 24 25 template <class T> struct A { 26 void f() { C::foo(); } 27 }; 28 29 template <class T> struct A<T*> { 30 void f() { C::foo(); } 31 }; 32 33 template <> struct A<char> { 34 void f() { C::foo(); } 35 }; 36 } 37 38 // FIXME: these should fail! 39 namespace test2 { 40 template <class T> struct A; 41 42 class C { 43 static void foo(); 44 template <class T> friend void A<T>::g(); 45 }; 46 47 template <class T> struct A { 48 void f() { C::foo(); } 49 }; 50 51 template <class T> struct A<T*> { 52 void f() { C::foo(); } 53 }; 54 55 template <> struct A<char> { 56 void f() { C::foo(); } 57 }; 58 } 59 60 // Tests 3, 4 and 5 were all noted in <rdar://problem/8540527>. 61 namespace test3 { 62 template <class T> struct A { 63 struct Inner { 64 static int foo(); 65 }; 66 }; 67 68 template <class U> class C { 69 int i; 70 template <class T> friend struct A<T>::Inner; 71 }; 72 73 template <class T> int A<T>::Inner::foo() { 74 C<int> c; 75 c.i = 0; 76 return 0; 77 } 78 79 int test = A<int>::Inner::foo(); 80 } 81 82 namespace test4 { 83 template <class T> struct X { 84 template <class U> void operator+=(U); 85 86 template <class V> 87 template <class U> 88 friend void X<V>::operator+=(U); 89 }; 90 91 void test() { 92 X<int>() += 1.0; 93 } 94 } 95 96 namespace test5 { 97 template<template <class> class T> struct A { 98 template<template <class> class T> friend void A<T>::foo(); 99 }; 100 101 template <class> struct B {}; 102 template class A<B>; 103 } 104