summaryrefslogtreecommitdiffstats
path: root/test/SemaTemplate/instantiate-member-template.cpp
blob: 04ced926341a99b2187b72b3dd55c321ef550572 (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
130
131
132
133
// RUN: clang-cc -fsyntax-only -verify %s

template<typename T>
struct X0 {
  template<typename U> T f0(U);
  template<typename U> U& f1(T*, U); // expected-error{{pointer to a reference}} \
                                     // expected-note{{candidate}}
};

X0<int> x0i;
X0<void> x0v;
X0<int&> x0ir; // expected-note{{instantiation}}

void test_X0(int *ip, double *dp) {
  X0<int> xi;
  int i1 = xi.f0(ip);
  double *&dpr = xi.f1(ip, dp);
  xi.f1(dp, dp); // expected-error{{no matching}}

  X0<void> xv;
  double *&dpr2 = xv.f1(ip, dp);
}

template<typename T>
struct X1 {
  template<typename U>
  struct Inner0 {
    U x; 
    T y; // expected-error{{void}}
  };

  template<typename U>
  struct Inner1 {
    U x; // expected-error{{void}}
    T y;
  };
  
  template<typename U>
  struct Inner2 {
    struct SuperInner {
      U z; // expected-error{{void}}
    };
  };
  
  template<typename U>
  struct Inner3 {
    void f0(T t, U u) {
      (void)(t + u); // expected-error{{invalid operands}}
    }
    
    template<typename V>
    V f1(T t, U u, V) {
      return t + u; // expected-error{{incompatible type}}
    }
  };
  
  template<typename U>
  struct Inner4;
};

template<typename T>
template<typename U>
struct X1<T>::Inner4 {
  template<typename V>
  V f2(T t, U u, V);
  
  static U value;
};

template<typename T>
template<typename U>
U X1<T>::Inner4<U>::value; // expected-error{{reference variable}}

template<typename T>
template<typename U>
template<typename V>
V X1<T>::Inner4<U>::f2(T t, U u, V) {
  return t + u; // expected-error{{incompatible type}}
}

void test_X1(int *ip, int i, double *dp) {
  X1<void>::Inner0<int> *xvip; // okay
  X1<void>::Inner0<int> xvi; // expected-note{{instantiation}}
  
  X1<int>::Inner1<void> *xivp; // okay
  X1<int>::Inner1<void> xiv; // expected-note{{instantiation}}
  
  X1<int>::Inner2<void>::SuperInner *xisivp; // okay
  X1<int>::Inner2<void>::SuperInner xisiv; // expected-note{{instantiation}}
  
  X1<int*>::Inner3<int> id3;
  id3.f0(ip, i);
  id3.f0(dp, i); // expected-error{{incompatible type}}
  id3.f1(ip, i, ip);
  id3.f1(ip, i, dp); // expected-note{{instantiation}}
  
  X1<int*>::Inner3<double*> id3b;
  id3b.f0(ip, dp); // expected-note{{instantiation}}
  
  X1<int*>::Inner4<int> id4;
  id4.f2(ip, i, dp); // expected-note{{instantiation}}
  
  X1<int*>::Inner4<int>::value = 17;
  i = X1<int*>::Inner4<int&>::value; // expected-note{{instantiation}}
}


template<typename T>
struct X2 {
  template<T *Ptr> // expected-error{{pointer to a reference}}
  struct Inner;
  
  template<T Value> // expected-error{{cannot have type 'float'}}
  struct Inner2;
};

X2<int&> x2a; // expected-note{{instantiation}}
X2<float> x2b; // expected-note{{instantiation}}

namespace N0 {
  template<typename T>
  struct X0 { };
  
  struct X1 {
    template<typename T> void f(X0<T>& vals) { g(vals); }
    template<typename T> void g(X0<T>& vals) { }
  };
  
  void test(X1 x1, X0<int> x0i, X0<long> x0l) {
    x1.f(x0i);
    x1.f(x0l);
  }  
}
OpenPOWER on IntegriCloud