add opensuse toolchain support, patch by Ismail Donmez!
[clang/stm8.git] / test / SemaTemplate / typename-specifier-4.cpp
blob44cf966e33b593e0e2b5a3a82c459db64f9815f0
1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 template<typename T, typename U>
3 struct is_same {
4 static const bool value = false;
5 };
7 template<typename T>
8 struct is_same<T, T> {
9 static const bool value = true;
12 template<typename MetaFun, typename T1, typename T2>
13 struct metafun_apply2 {
14 typedef typename MetaFun::template apply<T1, T2> inner;
15 typedef typename inner::type type;
18 template<typename T, typename U> struct pair;
20 struct make_pair {
21 template<typename T1, typename T2>
22 struct apply {
23 typedef pair<T1, T2> type;
27 int a0[is_same<metafun_apply2<make_pair, int, float>::type,
28 pair<int, float> >::value? 1 : -1];
29 int a1[is_same<
30 typename make_pair::template apply<int, float>, // expected-warning{{'template' keyword outside of a template}} \
31 // expected-warning{{'typename' occurs outside of a template}}
32 make_pair::apply<int, float>
33 >::value? 1 : -1];
35 template<typename MetaFun>
36 struct swap_and_apply2 {
37 template<typename T1, typename T2>
38 struct apply {
39 typedef typename MetaFun::template apply<T2, T1> new_metafun;
40 typedef typename new_metafun::type type;
44 int a2[is_same<swap_and_apply2<make_pair>::apply<int, float>::type,
45 pair<float, int> >::value? 1 : -1];
47 template<typename MetaFun>
48 struct swap_and_apply2b {
49 template<typename T1, typename T2>
50 struct apply {
51 typedef typename MetaFun::template apply<T2, T1>::type type;
55 int a3[is_same<swap_and_apply2b<make_pair>::apply<int, float>::type,
56 pair<float, int> >::value? 1 : -1];
58 template<typename T>
59 struct X0 {
60 template<typename U, typename V>
61 struct Inner;
63 void f0(X0<T>::Inner<T*, T&>); // expected-note{{here}}
64 void f0(typename X0<T>::Inner<T*, T&>); // expected-error{{redecl}}
66 void f1(X0<T>::Inner<T*, T&>); // expected-note{{here}}
67 void f1(typename X0<T>::template Inner<T*, T&>); // expected-error{{redecl}}
69 void f2(typename X0<T>::Inner<T*, T&>::type); // expected-note{{here}}
70 void f2(typename X0<T>::template Inner<T*, T&>::type); // expected-error{{redecl}}
73 namespace PR6236 {
74 template<typename T, typename U> struct S { };
76 template<typename T> struct S<T, T> {
77 template<typename U> struct K { };
79 void f() {
80 typedef typename S<T, T>::template K<T> Foo;
85 namespace PR6268 {
86 template <typename T>
87 struct Outer {
88 template <typename U>
89 struct Inner {};
91 template <typename U>
92 typename Outer<T>::template Inner<U>
93 foo(typename Outer<T>::template Inner<U>);
96 template <typename T>
97 template <typename U>
98 typename Outer<T>::template Inner<U>
99 Outer<T>::foo(typename Outer<T>::template Inner<U>) {
100 return Inner<U>();
104 namespace PR6463 {
105 struct B { typedef int type; }; // expected-note 2{{member found by ambiguous name lookup}}
106 struct C { typedef int type; }; // expected-note 2{{member found by ambiguous name lookup}}
108 template<typename T>
109 struct A : B, C {
110 type& a(); // expected-error{{found in multiple base classes}}
111 int x;
114 // FIXME: Improve source location info here.
115 template<typename T>
116 typename A<T>::type& A<T>::a() { // expected-error{{found in multiple base classes}}
117 return x;
121 namespace PR7419 {
122 template <typename T> struct S {
123 typedef typename T::Y T2;
124 typedef typename T2::Z T3;
125 typedef typename T3::W T4;
126 T4 *f();
128 typedef typename T::template Y<int> TT2;
129 typedef typename TT2::template Z<float> TT3;
130 typedef typename TT3::template W<double> TT4;
131 TT4 g();
134 template <typename T> typename T::Y::Z::W *S<T>::f() { }
135 template <typename T> typename T::template Y<int>::template Z<float>::template W<double> S<T>::g() { }
138 namespace rdar8740998 {
139 template<typename T>
140 struct X : public T {
141 using T::iterator; // expected-note{{add 'typename' to treat this using declaration as a type}} \
142 // expected-error{{dependent using declaration resolved to type without 'typename'}}
144 void f() {
145 typename X<T>::iterator i; // expected-error{{typename specifier refers to a dependent using declaration for a value 'iterator' in 'X<T>'}}
149 struct HasIterator {
150 typedef int *iterator; // expected-note{{target of using declaration}}
153 void test_X(X<HasIterator> xi) { // expected-note{{in instantiation of template class}}
154 xi.f();
158 namespace rdar9068589 {
159 // From GCC PR c++/13950
160 template <class T> struct Base {};
161 template <class T> struct Derived: public Base<T> {
162 typename Derived::template Base<double>* p1;