summaryrefslogtreecommitdiffstats
path: root/test/SemaTemplate/friend-template.cpp
blob: 6ee30aa7775a5733e5b5216667dd7ac93b689014 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// RUN: %clang_cc1 -fsyntax-only -verify %s
// PR5057
namespace test0 {
  namespace std {
    class X {
    public:
      template<typename T> friend struct Y;
    };
  }

  namespace std {
    template<typename T> struct Y {};
  }
}

namespace test1 {
  template<typename T> void f1(T) { } // expected-note{{here}}

  class X {
    template<typename T> friend void f0(T);
    template<typename T> friend void f1(T);
  };

  template<typename T> void f0(T) { }
  template<typename T> void f1(T) { } // expected-error{{redefinition}}
}

// PR4768
namespace test2 {
  template<typename T> struct X0 {
    template<typename U> friend struct X0;
  };
  
  template<typename T> struct X0<T*> {
    template<typename U> friend struct X0;
  };

  template<> struct X0<int> {
    template<typename U> friend struct X0;
  };

  template<typename T> struct X1 {
    template<typename U> friend void f2(U);
    template<typename U> friend void f3(U);
  };

  template<typename U> void f2(U);

  X1<int> x1i;
  X0<int*> x0ip;

  template<> void f2(int);

  // FIXME: Should this declaration of f3 be required for the specialization of
  // f3<int> (further below) to work? GCC and EDG don't require it, we do...
  template<typename U> void f3(U);

  template<> void f3(int);
}

// PR5332
namespace test3 {
  template <typename T> class Foo {
    template <typename U>
    friend class Foo;
  };

  Foo<int> foo;

  template<typename T, T Value> struct X2a;

  template<typename T, int Size> struct X2b;

  template<typename T>
  class X3 {
    template<typename U, U Value> friend struct X2a;

    // FIXME: the redeclaration note ends up here because redeclaration
    // lookup ends up finding the friend target from X3<int>.
    template<typename U, T Value> friend struct X2b; // expected-error {{template non-type parameter has a different type 'long' in template redeclaration}} \
      // expected-note {{previous non-type template parameter with type 'int' is here}}
  };

  X3<int> x3i; // okay

  X3<long> x3l; // expected-note {{in instantiation}}
}

// PR5716
namespace test4 {
  template<typename> struct A {
    template<typename T> friend void f(const A<T>&);
  };

  template<typename T> void f(const A<T>&) {
    int a[sizeof(T) ? -1 : -1]; // expected-error {{array size is negative}}
  }

  void f() {
    f(A<int>()); // expected-note {{in instantiation of function template specialization}}
  }
}

namespace test5 {
  class outer {
    class foo;
    template <typename T> friend struct cache;
  };
  class outer::foo {
    template <typename T> friend struct cache;
  };
}

// PR6022
namespace PR6022 {
  template <class T1, class T2 , class T3  > class A;

  namespace inner {
    template<class T1, class T2, class T3, class T> 
    A<T1, T2, T3>& f0(A<T1, T2, T3>&, T);
  } 

  template<class T1, class T2, class T3>
  class A {
    template<class U1, class U2, class U3, class T>  
    friend A<U1, U2, U3>& inner::f0(A<U1, U2, U3>&, T);
  };
}

OpenPOWER on IntegriCloud