[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / SemaTemplate / typename-specifier-4.cpp
blob7aa2b8da510819c16e0db6fe30e7e462ad4a438c
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
4 template<typename T, typename U>
5 struct is_same {
6 static const bool value = false;
7 };
9 template<typename T>
10 struct is_same<T, T> {
11 static const bool value = true;
14 template<typename MetaFun, typename T1, typename T2>
15 struct metafun_apply2 {
16 typedef typename MetaFun::template apply<T1, T2> inner;
17 typedef typename inner::type type;
20 template<typename T, typename U> struct pair;
22 struct make_pair {
23 template<typename T1, typename T2>
24 struct apply {
25 typedef pair<T1, T2> type;
29 int a0[is_same<metafun_apply2<make_pair, int, float>::type,
30 pair<int, float> >::value? 1 : -1];
31 int 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];
40 template<typename MetaFun>
41 struct 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;
49 int a2[is_same<swap_and_apply2<make_pair>::apply<int, float>::type,
50 pair<float, int> >::value? 1 : -1];
52 template<typename MetaFun>
53 struct swap_and_apply2b {
54 template<typename T1, typename T2>
55 struct apply {
56 typedef typename MetaFun::template apply<T2, T1>::type type;
60 int a3[is_same<swap_and_apply2b<make_pair>::apply<int, float>::type,
61 pair<float, int> >::value? 1 : -1];
63 template<typename T>
64 struct X0 {
65 template<typename U, typename V>
66 struct Inner;
68 void f0(X0<T>::Inner<T*, T&>); // expected-note{{here}}
69 void f0(typename X0<T>::Inner<T*, T&>); // expected-error{{redecl}}
71 void f1(X0<T>::Inner<T*, T&>); // expected-note{{here}}
72 void f1(typename X0<T>::template Inner<T*, T&>); // expected-error{{redecl}}
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}}
78 namespace PR6236 {
79 template<typename T, typename U> struct S { };
81 template<typename T> struct S<T, T> {
82 template<typename U> struct K { };
84 void f() {
85 typedef typename S<T, T>::template K<T> Foo;
90 namespace PR6268 {
91 template <typename T>
92 struct Outer {
93 template <typename U>
94 struct Inner {};
96 template <typename U>
97 typename Outer<T>::template Inner<U>
98 foo(typename Outer<T>::template Inner<U>);
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>();
109 namespace PR6463 {
110 struct B { typedef int type; }; // expected-note 2{{member type 'int' found by ambiguous name lookup}}
111 struct C { typedef const int type; }; // expected-note 2{{member type 'const int' found by ambiguous name lookup}}
113 template<typename T>
114 struct A : B, C {
115 type& a(); // expected-error{{found in multiple base classes}}
116 int x;
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;
126 namespace 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();
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();
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() { }
143 namespace 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'}}
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>'}}
154 struct HasIterator {
155 typedef int *iterator; // expected-note{{target of using declaration}}
158 void test_X(X<HasIterator> xi) { // expected-note{{in instantiation of template class}}
159 xi.f();
163 namespace 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;