13573b2c84372d9484296fa658f5276f6c09acb92Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only -verify %s
285c95262de036719f872ae38187d751e575df82eJeffrey Yasskintemplate<typename T> class A; // expected-note 2 {{template parameter is declared here}} expected-note{{template is declared here}}
335d81bb3324970c340d63aa9e17c39694dfe2891Douglas Gregor
435d81bb3324970c340d63aa9e17c39694dfe2891Douglas Gregor// [temp.arg.type]p1
50c281a89b43f1e71e906d8b9733c2eb0303e87dcDouglas GregorA<0> *a1; // expected-error{{template argument for template type parameter must be a type}}
635d81bb3324970c340d63aa9e17c39694dfe2891Douglas Gregor
785c95262de036719f872ae38187d751e575df82eJeffrey YasskinA<A> *a2; // expected-error{{use of class template A requires template arguments}}
835d81bb3324970c340d63aa9e17c39694dfe2891Douglas Gregor
935d81bb3324970c340d63aa9e17c39694dfe2891Douglas GregorA<int> *a3;
10341ac795fdda52b74de7ba824b15ea51d77ae2fbDouglas GregorA<int()> *a4;
11341ac795fdda52b74de7ba824b15ea51d77ae2fbDouglas GregorA<int(float)> *a5;
1235d81bb3324970c340d63aa9e17c39694dfe2891Douglas GregorA<A<int> > *a6;
1335d81bb3324970c340d63aa9e17c39694dfe2891Douglas Gregor
1485c95262de036719f872ae38187d751e575df82eJeffrey Yasskin// Pass an overloaded function template:
1585c95262de036719f872ae38187d751e575df82eJeffrey Yasskintemplate<typename T> void function_tpl(T);
1685c95262de036719f872ae38187d751e575df82eJeffrey YasskinA<function_tpl> a7;  // expected-error{{template argument for template type parameter must be a type}}
1785c95262de036719f872ae38187d751e575df82eJeffrey Yasskin
1885c95262de036719f872ae38187d751e575df82eJeffrey Yasskin// Pass a qualified name:
1985c95262de036719f872ae38187d751e575df82eJeffrey Yasskinnamespace ns {
2085c95262de036719f872ae38187d751e575df82eJeffrey Yasskintemplate<typename T> class B {};  // expected-note{{template is declared here}}
2185c95262de036719f872ae38187d751e575df82eJeffrey Yasskin}
2285c95262de036719f872ae38187d751e575df82eJeffrey YasskinA<ns::B> a8; // expected-error{{use of class template ns::B requires template arguments}}
2385c95262de036719f872ae38187d751e575df82eJeffrey Yasskin
2435d81bb3324970c340d63aa9e17c39694dfe2891Douglas Gregor// [temp.arg.type]p2
2535d81bb3324970c340d63aa9e17c39694dfe2891Douglas Gregorvoid f() {
2635d81bb3324970c340d63aa9e17c39694dfe2891Douglas Gregor  class X { };
275eb667af08d8619c455d6f53e7d59aab8831c187Chandler Carruth  A<X> * a = 0; // expected-warning{{template argument uses local type 'X'}}
2835d81bb3324970c340d63aa9e17c39694dfe2891Douglas Gregor}
2935d81bb3324970c340d63aa9e17c39694dfe2891Douglas Gregor
3035d81bb3324970c340d63aa9e17c39694dfe2891Douglas Gregorstruct { int x; } Unnamed; // expected-note{{unnamed type used in template argument was declared here}}
315eb667af08d8619c455d6f53e7d59aab8831c187Chandler CarruthA<__typeof__(Unnamed)> *a9; // expected-warning{{template argument uses unnamed type}}
3235d81bb3324970c340d63aa9e17c39694dfe2891Douglas Gregor
33c2cf9ebd6b9b63135ac0af342a4a12b9c546c420Douglas Gregortemplate<typename T, unsigned N>
34c2cf9ebd6b9b63135ac0af342a4a12b9c546c420Douglas Gregorstruct Array {
35c2cf9ebd6b9b63135ac0af342a4a12b9c546c420Douglas Gregor  typedef struct { T x[N]; } type;
36c2cf9ebd6b9b63135ac0af342a4a12b9c546c420Douglas Gregor};
37c2cf9ebd6b9b63135ac0af342a4a12b9c546c420Douglas Gregor
38c2cf9ebd6b9b63135ac0af342a4a12b9c546c420Douglas Gregortemplate<typename T> struct A1 { };
39c2cf9ebd6b9b63135ac0af342a4a12b9c546c420Douglas GregorA1<Array<int, 17>::type> ax;
40c2cf9ebd6b9b63135ac0af342a4a12b9c546c420Douglas Gregor
4135d81bb3324970c340d63aa9e17c39694dfe2891Douglas Gregor// FIXME: [temp.arg.type]p3. The check doesn't really belong here (it
4235d81bb3324970c340d63aa9e17c39694dfe2891Douglas Gregor// belongs somewhere in the template instantiation section).
43