Clang Project

clang_source_code/test/SemaTemplate/typename-specifier-4.cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %s
2// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
3// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
4template<typename T, typename U> 
5struct is_same {
6  static const bool value = false;
7};
8
9template<typename T>
10struct is_same<T, T> {
11  static const bool value = true;
12};
13
14template<typename MetaFun, typename T1, typename T2>
15struct metafun_apply2 {
16  typedef typename MetaFun::template apply<T1, T2> inner;
17  typedef typename inner::type type;
18};
19
20template<typename T, typename U> struct pair;
21
22struct make_pair {
23  template<typename T1, typename T2>
24  struct apply {
25    typedef pair<T1, T2> type;
26  };
27};
28
29int a0[is_same<metafun_apply2<make_pair, int, float>::type, 
30               pair<int, float> >::value? 1 : -1];
31int a1[is_same<
32         typename make_pair::template apply<int, float>, 
33#if __cplusplus <= 199711L // C++03 and earlier modes
34         // expected-warning@-2 {{'template' keyword outside of a template}}
35         // expected-warning@-3 {{'typename' occurs outside of a template}}
36#endif
37         make_pair::apply<int, float>
38       >::value? 1 : -1];
39
40template<typename MetaFun>
41struct swap_and_apply2 {
42  template<typename T1, typename T2>
43  struct apply {
44    typedef typename MetaFun::template apply<T2, T1> new_metafun;
45    typedef typename new_metafun::type type;
46  };
47};
48
49int a2[is_same<swap_and_apply2<make_pair>::apply<int, float>::type, 
50               pair<float, int> >::value? 1 : -1];
51
52template<typename MetaFun>
53struct swap_and_apply2b {
54  template<typename T1, typename T2>
55  struct apply {
56    typedef typename MetaFun::template apply<T2, T1>::type type;
57  };
58};
59
60int a3[is_same<swap_and_apply2b<make_pair>::apply<int, float>::type, 
61               pair<float, int> >::value? 1 : -1];
62
63template<typename T>
64struct X0 {
65  template<typename U, typename V>
66  struct Inner;
67  
68  void f0(X0<T>::Inner<T*, T&>); // expected-note{{here}}
69  void f0(typename X0<T>::Inner<T*, T&>); // expected-error{{redecl}}
70
71  void f1(X0<T>::Inner<T*, T&>); // expected-note{{here}}
72  void f1(typename X0<T>::template Inner<T*, T&>); // expected-error{{redecl}}
73
74  void f2(typename X0<T>::Inner<T*, T&>::type); // expected-note{{here}}
75  void f2(typename X0<T>::template Inner<T*, T&>::type); // expected-error{{redecl}}
76};
77
78namespace PR6236 {
79  template<typename T, typename U> struct S { };
80  
81  template<typename T> struct S<T, T> {
82    template<typename U> struct K { };
83    
84    void f() {
85      typedef typename S<T, T>::template K<T> Foo;
86    }
87  };
88}
89
90namespace PR6268 {
91  template <typename T>
92  struct Outer {
93    template <typename U>
94    struct Inner {};
95
96    template <typename U>
97    typename Outer<T>::template Inner<U>
98    foo(typename Outer<T>::template Inner<U>);
99  };
100
101  template <typename T>
102  template <typename U>
103  typename Outer<T>::template Inner<U>
104  Outer<T>::foo(typename Outer<T>::template Inner<U>) {
105    return Inner<U>();
106  }
107}
108
109namespace PR6463 {
110  struct B { typedef int type; }; // expected-note 2{{member found by ambiguous name lookup}}
111  struct C { typedef int type; }; // expected-note 2{{member found by ambiguous name lookup}}
112
113  template<typename T>
114  struct A : B, C { 
115    type& a(); // expected-error{{found in multiple base classes}}
116    int x; 
117  };
118
119  // FIXME: Improve source location info here.
120  template<typename T>
121  typename A<T>::type& A<T>::a() { // expected-error{{found in multiple base classes}}
122    return x;
123  }
124}
125
126namespace PR7419 {
127  template <typename T> struct S {
128    typedef typename T::Y T2;
129    typedef typename T2::Z T3;
130    typedef typename T3::W T4;
131    T4 *f();
132
133    typedef typename T::template Y<int> TT2;
134    typedef typename TT2::template Z<float> TT3;
135    typedef typename TT3::template W<double> TT4;
136    TT4 g();
137  };
138
139  template <typename T> typename T::Y::Z::W *S<T>::f() { }
140  template <typename T> typename T::template Y<int>::template Z<float>::template W<double> S<T>::g() { }
141}
142
143namespace rdar8740998 {
144  template<typename T>
145  struct X : public T {
146    using T::iterator; // expected-note{{add 'typename' to treat this using declaration as a type}} \
147    // expected-error{{dependent using declaration resolved to type without 'typename'}}
148
149    void f() {
150      typename X<T>::iterator i; // expected-error{{typename specifier refers to a dependent using declaration for a value 'iterator' in 'X<T>'}}
151    }
152  };
153
154  struct HasIterator {
155    typedef int *iterator; // expected-note{{target of using declaration}}
156  };
157
158  void test_X(X<HasIterator> xi) { // expected-note{{in instantiation of template class}}
159    xi.f();
160  }
161}
162
163namespace rdar9068589 {
164  // From GCC PR c++/13950
165  template <class T> struct Base {};
166  template <class T> struct Derived: public Base<T> {
167    typename Derived::template Base<double>* p1;
168  };
169}
170