1a5728872c7702ddd09537c95bc3cbd20e1f2fb09Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only -verify %s
2db88d8ad74097e2601d81ee863ce46a8a48a7034Jeffrey Yasskintemplate<typename T> class A; // expected-note 2 {{template parameter is declared here}} expected-note{{template is declared here}}
3c15cb38a4ff717097b32532fbf761c71b1376a02Douglas Gregor
4c15cb38a4ff717097b32532fbf761c71b1376a02Douglas Gregor// [temp.arg.type]p1
539a8de10c18365bde7062d8959b7ed525449c561Douglas GregorA<0> *a1; // expected-error{{template argument for template type parameter must be a type}}
6c15cb38a4ff717097b32532fbf761c71b1376a02Douglas Gregor
74b02dff7aebb98d2d60b2ff4d3fc86109213128cDavid BlaikieA<A> *a2; // expected-error{{use of class template 'A' requires template arguments}}
8c15cb38a4ff717097b32532fbf761c71b1376a02Douglas Gregor
9c15cb38a4ff717097b32532fbf761c71b1376a02Douglas GregorA<int> *a3;
108b642592a35167a3780074e78674e0bece87c40cDouglas GregorA<int()> *a4;
118b642592a35167a3780074e78674e0bece87c40cDouglas GregorA<int(float)> *a5;
12c15cb38a4ff717097b32532fbf761c71b1376a02Douglas GregorA<A<int> > *a6;
13c15cb38a4ff717097b32532fbf761c71b1376a02Douglas Gregor
14db88d8ad74097e2601d81ee863ce46a8a48a7034Jeffrey Yasskin// Pass an overloaded function template:
15db88d8ad74097e2601d81ee863ce46a8a48a7034Jeffrey Yasskintemplate<typename T> void function_tpl(T);
16db88d8ad74097e2601d81ee863ce46a8a48a7034Jeffrey YasskinA<function_tpl> a7;  // expected-error{{template argument for template type parameter must be a type}}
17db88d8ad74097e2601d81ee863ce46a8a48a7034Jeffrey Yasskin
18db88d8ad74097e2601d81ee863ce46a8a48a7034Jeffrey Yasskin// Pass a qualified name:
19db88d8ad74097e2601d81ee863ce46a8a48a7034Jeffrey Yasskinnamespace ns {
20db88d8ad74097e2601d81ee863ce46a8a48a7034Jeffrey Yasskintemplate<typename T> class B {};  // expected-note{{template is declared here}}
21db88d8ad74097e2601d81ee863ce46a8a48a7034Jeffrey Yasskin}
224b02dff7aebb98d2d60b2ff4d3fc86109213128cDavid BlaikieA<ns::B> a8; // expected-error{{use of class template 'ns::B' requires template arguments}}
23db88d8ad74097e2601d81ee863ce46a8a48a7034Jeffrey Yasskin
24c15cb38a4ff717097b32532fbf761c71b1376a02Douglas Gregor// [temp.arg.type]p2
25c15cb38a4ff717097b32532fbf761c71b1376a02Douglas Gregorvoid f() {
26c15cb38a4ff717097b32532fbf761c71b1376a02Douglas Gregor  class X { };
2717fb855280be411389361f1c79753e0013c4187cChandler Carruth  A<X> * a = 0; // expected-warning{{template argument uses local type 'X'}}
28c15cb38a4ff717097b32532fbf761c71b1376a02Douglas Gregor}
29c15cb38a4ff717097b32532fbf761c71b1376a02Douglas Gregor
30c15cb38a4ff717097b32532fbf761c71b1376a02Douglas Gregorstruct { int x; } Unnamed; // expected-note{{unnamed type used in template argument was declared here}}
3117fb855280be411389361f1c79753e0013c4187cChandler CarruthA<__typeof__(Unnamed)> *a9; // expected-warning{{template argument uses unnamed type}}
32c15cb38a4ff717097b32532fbf761c71b1376a02Douglas Gregor
33d57a38ee02c285d69d05fed6df0d7406b2517888Douglas Gregortemplate<typename T, unsigned N>
34d57a38ee02c285d69d05fed6df0d7406b2517888Douglas Gregorstruct Array {
35d57a38ee02c285d69d05fed6df0d7406b2517888Douglas Gregor  typedef struct { T x[N]; } type;
36d57a38ee02c285d69d05fed6df0d7406b2517888Douglas Gregor};
37d57a38ee02c285d69d05fed6df0d7406b2517888Douglas Gregor
38d57a38ee02c285d69d05fed6df0d7406b2517888Douglas Gregortemplate<typename T> struct A1 { };
39d57a38ee02c285d69d05fed6df0d7406b2517888Douglas GregorA1<Array<int, 17>::type> ax;
40d57a38ee02c285d69d05fed6df0d7406b2517888Douglas Gregor
41c15cb38a4ff717097b32532fbf761c71b1376a02Douglas Gregor// FIXME: [temp.arg.type]p3. The check doesn't really belong here (it
42c15cb38a4ff717097b32532fbf761c71b1376a02Douglas Gregor// belongs somewhere in the template instantiation section).
43