1 // RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-unused
2 // RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-unused -fms-compatibility -DMSVC
3 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s -Wno-unused
4 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s -Wno-unused -fms-compatibility -DMSVC
5 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -Wno-unused
6 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -Wno-unused -fms-compatibility -DMSVC
17 int type
; // expected-note 2{{referenced member 'type' is declared here}}
23 typename
N::A::type
*ip1
= &i
;
24 #if __cplusplus <= 199711L // C++03 or earlier modes
25 // expected-warning@-2 {{'typename' occurs outside of a template}}
27 typename
N::B::type
*ip2
= &i
; // expected-error{{no type named 'type' in 'N::B'}}
28 #if __cplusplus <= 199711L
29 // expected-warning@-2 {{'typename' occurs outside of a template}}
31 typename
N::C::type
*ip3
= &i
; // expected-error{{typename specifier refers to non-type member 'type'}}
32 #if __cplusplus <= 199711L
33 // expected-warning@-2 {{'typename' occurs outside of a template}}
37 typename
N::A::type
f(typename
N::A::type(a
)); // expected-warning{{disambiguated as a function declaration}}
38 // expected-note@-1 {{add a pair of parentheses}}
39 #if __cplusplus <= 199711L
40 // expected-warning@-3 2{{'typename' occurs outside of a template}}
45 for (typename
A::type i
= 0; i
< 10; ++i
)
46 #if __cplusplus <= 199711L
47 // expected-warning@-2 {{'typename' occurs outside of a template}}
51 const typename
N::A::type
f2(d
);
52 #if __cplusplus <= 199711L
53 // expected-warning@-2 {{'typename' occurs outside of a template}}
60 typedef typename
T::type type
; // expected-error {{no type named 'type' in 'N::B'}} \
61 // expected-error {{no type named 'type' in 'B'}} \
62 // FIXME: location info for error above isn't very good \
63 // expected-error 2{{typename specifier refers to non-type member 'type'}} \
64 // expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
68 N::X
<N::A
>::type
*ip4
= &i
;
69 N::X
<N::B
>::type
*ip5
= &i
; // expected-note{{in instantiation of template class 'N::X<N::B>' requested here}}
70 N::X
<N::C
>::type
*ip6
= &i
; // expected-note{{in instantiation of template class 'N::X<N::C>' requested here}}
72 N::X
<int>::type fail1
; // expected-note{{in instantiation of template class 'N::X<int>' requested here}}
76 typedef typename
N::X
<T
>::type
*type
; // expected-note{{in instantiation of template class 'N::X<B>' requested here}} \
77 // expected-note{{in instantiation of template class 'N::X<C>' requested here}}
89 int type
; // expected-note{{referenced member 'type' is declared here}}
92 ::Y
<A
>::type ip7
= &i
;
93 ::Y
<B
>::type ip8
= &i
; // expected-note{{in instantiation of template class 'Y<B>' requested here}}
94 ::Y
<C
>::type ip9
= &i
; // expected-note{{in instantiation of template class 'Y<C>' requested here}}
96 template<typename T
> struct D
{
97 typedef typename
T::foo foo
; // expected-error {{type 'long' cannot be used prior to '::' because it has no members}}
98 typedef typename
foo::bar bar
;
101 D
<long> struct_D
; // expected-note {{in instantiation of template class 'D<long>' requested here}}
103 template<typename T
> struct E
{
104 typedef typename
T::foo foo
;
105 typedef typename
foo::bar bar
; // expected-error {{type 'E<F>::foo' (aka 'double') cannot be used prior to '::' because it has no members}}
112 E
<F
> struct_E
; // expected-note {{in instantiation of template class 'E<F>' requested here}}
114 template<typename T
> struct G
{
115 typedef typename
T::foo foo
;
116 typedef typename
foo::bar bar
;
128 template< int mydim
, typename Traits
>
131 typedef int some_type_t
;
134 template<class ctype
, int mydim
, int coorddim
>
135 class MockGeometry
: BasicGeometry
<mydim
, int>{
136 using typename BasicGeometry
<mydim
, int>::operator[]; // expected-error {{typename is allowed for identifiers only}}
141 namespace missing_typename
{
142 template <class T1
, class T2
> struct pair
{}; // expected-note 7 {{template parameter is declared here}}
144 template <class T1
, class T2
>
146 typedef T1
* iterator
;
150 class ExampleClass1
{
154 struct ExampleItemSet
{
155 typedef ExampleItem
* iterator
;
156 ExampleItem
* operator[](unsigned);
161 // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
163 // expected-error@+2 {{template argument for template type parameter must be a type; did you forget 'typename'?}}
165 pair
<ExampleItemSet::iterator
, int> i
;
166 pair
<this->ExampleItemSet::iterator
, int> i
; // expected-error-re {{template argument for template type parameter must be a type{{$}}}}
167 pair
<ExampleItemSet::operator[], int> i
; // expected-error-re {{template argument for template type parameter must be a type{{$}}}}
170 // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
172 // expected-error@+2 {{template argument for template type parameter must be a type; did you forget 'typename'?}}
174 pair
<ExampleItemSet::iterator
, int> elt
;
177 typedef map
<int, ExampleItem
*> ExampleItemMap
;
181 // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
183 // expected-error@+2 {{template argument for template type parameter must be a type; did you forget 'typename'?}}
185 pair
<ExampleItemMap::iterator
, int> i
;
188 // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
190 // expected-error@+2 {{template argument for template type parameter must be a type; did you forget 'typename'?}}
192 pair
<ExampleItemMap::iterator
, int> entry
;
193 pair
<bar
, int> foobar
; // expected-error {{template argument for template type parameter must be a type}}
195 } // namespace missing_typename
197 namespace missing_typename_and_base
{
198 template <class T
> struct Bar
{}; // expected-note 1+ {{template parameter is declared here}}
199 template <typename T
>
202 // FIXME: MSVC accepts this code.
203 Bar
<TypeInBase
> x
; // expected-error {{use of undeclared identifier 'TypeInBase'}}
206 // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
208 // expected-error@+2 {{must be a type; did you forget 'typename'?}}
210 Bar
<T::TypeInBase
> y
;
213 // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
215 // expected-error@+2 {{must be a type; did you forget 'typename'?}}
217 Bar
<T::NestedRD::TypeInNestedRD
> z
;
221 typedef int TypeInBase
;
223 typedef int TypeInNestedRD
;
227 } // namespace missing_typename_and_base
229 namespace func_type_vs_construct_tmp
{
230 template <typename
> struct S
{ typedef int type
; };
231 template <typename T
> void f();
232 template <int N
> void f();
234 // expected-error@+1 {{missing 'typename' prior to dependent type name 'S<int>::type'}}
235 template <typename T
> void g() { f
</*typename*/ S
<T
>::type(int())>(); }
237 // Adding typename does fix the diagnostic.
238 template <typename T
> void h() { f
<typename S
<T
>::type(int())>(); }
241 g
<int>(); // expected-note-re {{in instantiation {{.*}} requested here}}
244 } // namespace func_type_vs_construct_tmp
246 namespace pointer_vs_multiply
{
248 // expected-error@+1 {{missing 'typename' prior to dependent type name 'B::type_or_int'}}
249 template <typename T
> void g() { T::type_or_int
* x
; }
250 // expected-error@+1 {{typename specifier refers to non-type member 'type_or_int' in 'pointer_vs_multiply::A'}}
251 template <typename T
> void h() { typename
T::type_or_int
* x
; }
253 struct A
{ static const int type_or_int
= 5; }; // expected-note {{referenced member 'type_or_int' is declared here}}
254 struct B
{ typedef int type_or_int
; };
258 g
<B
>(); // expected-note-re {{in instantiation {{.*}} requested here}}
259 h
<A
>(); // expected-note-re {{in instantiation {{.*}} requested here}}
262 } // namespace pointer_vs_multiply