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
>
6 static const bool value
= false;
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
;
23 template<typename T1
, typename T2
>
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];
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}}
37 make_pair::apply
<int, float>
40 template<typename MetaFun
>
41 struct swap_and_apply2
{
42 template<typename T1
, typename T2
>
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
>
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];
65 template<typename U
, typename V
>
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}}
79 template<typename T
, typename U
> struct S
{ };
81 template<typename T
> struct S
<T
, T
> {
82 template<typename U
> struct K
{ };
85 typedef typename S
<T
, T
>::template K
<T
> Foo
;
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
>) {
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}}
115 type
& a(); // expected-error{{found in multiple base classes}}
119 // FIXME: Improve source location info here.
121 typename A
<T
>::type
& A
<T
>::a() { // expected-error{{found in multiple base classes}}
127 template <typename T
> struct S
{
128 typedef typename
T::Y T2
;
129 typedef typename
T2::Z T3
;
130 typedef typename
T3::W T4
;
133 typedef typename
T::template Y
<int> TT2
;
134 typedef typename
TT2::template Z
<float> TT3
;
135 typedef typename
TT3::template W
<double> TT4
;
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
{
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'}}
150 typename X
<T
>::iterator i
; // expected-error{{typename specifier refers to a dependent using declaration for a value 'iterator' in 'X<T>'}}
155 typedef int *iterator
; // expected-note{{target of using declaration}}
158 void test_X(X
<HasIterator
> xi
) { // expected-note{{in instantiation of template class}}
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
;