temp_arg_nontype.cpp revision 4b2d3f7bcc4df31157df443af1b80bcaa9b58bba
18b642592a35167a3780074e78674e0bece87c40cDouglas Gregor// RUN: clang -fsyntax-only -std=c++98 -verify %s
26ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas Gregortemplate<int N> struct A; // expected-note 5{{template parameter is declared here}}
38b642592a35167a3780074e78674e0bece87c40cDouglas Gregor
48b642592a35167a3780074e78674e0bece87c40cDouglas GregorA<0> *a0;
58b642592a35167a3780074e78674e0bece87c40cDouglas Gregor
639a8de10c18365bde7062d8959b7ed525449c561Douglas GregorA<int()> *a1; // expected-error{{template argument for non-type template parameter is treated as type 'int (void)'}}
78b642592a35167a3780074e78674e0bece87c40cDouglas Gregor
839a8de10c18365bde7062d8959b7ed525449c561Douglas GregorA<int> *a2; // expected-error{{template argument for non-type template parameter must be an expression}}
98b642592a35167a3780074e78674e0bece87c40cDouglas Gregor
104b2d3f7bcc4df31157df443af1b80bcaa9b58bbaDouglas GregorA<1 >> 2> *a3; // expected-warning{{use of right-shift operator ('>>') in template argument will require parentheses in C++0x}}
118b642592a35167a3780074e78674e0bece87c40cDouglas Gregor
126ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas Gregor// C++ [temp.arg.nontype]p5:
136ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas GregorA<A> *a4; // expected-error{{must have an integral or enumeration type}} \
1439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor          // FIXME: the error message above is a bit lame
156ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas Gregor
166ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas Gregorenum E { Enumerator = 17 };
1739a8de10c18365bde7062d8959b7ed525449c561Douglas GregorA<E> *a5; // expected-error{{template argument for non-type template parameter must be an expression}}
186ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas Gregortemplate<E Value> struct A1; // expected-note{{template parameter is declared here}}
196ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas GregorA1<Enumerator> *a6; // okay
2039a8de10c18365bde7062d8959b7ed525449c561Douglas GregorA1<17> *a7; // expected-error{{non-type template argument of type 'int' cannot be converted to a value of type 'enum E'}}
216ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas Gregor
226ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas Gregorconst long LongValue = 12345678;
236ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas GregorA<LongValue> *a8;
246ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas Gregorconst short ShortValue = 17;
256ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas GregorA<ShortValue> *a9;
266ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas Gregor
276ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas Gregorint f(int);
2839a8de10c18365bde7062d8959b7ed525449c561Douglas GregorA<f(17)> *a10; // expected-error{{non-type template argument of type 'int' is not an integral constant expression}}
296ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas Gregor
306ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas Gregorclass X {
316ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas Gregorpublic:
32a35284bba5db7a6179d70fcce8fbe66481058698Douglas Gregor  X();
336ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas Gregor  X(int, int);
346ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas Gregor  operator int() const;
356ae5e6649f5d01a1b593f4db755bfcb42e095700Douglas Gregor};
3639a8de10c18365bde7062d8959b7ed525449c561Douglas GregorA<X(17, 42)> *a11; // expected-error{{non-type template argument of type 'class X' must have an integral or enumeration type}}
37a35284bba5db7a6179d70fcce8fbe66481058698Douglas Gregor
38a35284bba5db7a6179d70fcce8fbe66481058698Douglas Gregortemplate<X const *Ptr> struct A2;
39a35284bba5db7a6179d70fcce8fbe66481058698Douglas Gregor
40a35284bba5db7a6179d70fcce8fbe66481058698Douglas GregorX *X_ptr;
41cc45cb3630b42c5245e26593e385097c220bc859Douglas GregorX an_X;
42a35284bba5db7a6179d70fcce8fbe66481058698Douglas GregorX array_of_Xs[10];
43a35284bba5db7a6179d70fcce8fbe66481058698Douglas GregorA2<X_ptr> *a12;
44a35284bba5db7a6179d70fcce8fbe66481058698Douglas GregorA2<array_of_Xs> *a13;
45cc45cb3630b42c5245e26593e385097c220bc859Douglas GregorA2<&an_X> *a13_2;
4639a8de10c18365bde7062d8959b7ed525449c561Douglas GregorA2<(&an_X)> *a13_3; // expected-error{{non-type template argument cannot be surrounded by parentheses}}
47a35284bba5db7a6179d70fcce8fbe66481058698Douglas Gregor
48a35284bba5db7a6179d70fcce8fbe66481058698Douglas Gregorfloat f(float);
49a35284bba5db7a6179d70fcce8fbe66481058698Douglas Gregor
50a35284bba5db7a6179d70fcce8fbe66481058698Douglas Gregorfloat g(float);
51a35284bba5db7a6179d70fcce8fbe66481058698Douglas Gregordouble g(double);
52a35284bba5db7a6179d70fcce8fbe66481058698Douglas Gregor
53a35284bba5db7a6179d70fcce8fbe66481058698Douglas Gregorint h(int);
54a35284bba5db7a6179d70fcce8fbe66481058698Douglas Gregorfloat h2(float);
55a35284bba5db7a6179d70fcce8fbe66481058698Douglas Gregor
56a35284bba5db7a6179d70fcce8fbe66481058698Douglas Gregortemplate<int fp(int)> struct A3; // expected-note 2{{template parameter is declared here}}
57a35284bba5db7a6179d70fcce8fbe66481058698Douglas GregorA3<h> *a14_1;
58a35284bba5db7a6179d70fcce8fbe66481058698Douglas GregorA3<&h> *a14_2;
59a35284bba5db7a6179d70fcce8fbe66481058698Douglas GregorA3<f> *a14_3;
60a35284bba5db7a6179d70fcce8fbe66481058698Douglas GregorA3<&f> *a14_4;
6139a8de10c18365bde7062d8959b7ed525449c561Douglas GregorA3<h2> *a14_6;  // expected-error{{non-type template argument of type 'float (*)(float)' cannot be converted to a value of type 'int (*)(int)'}}
6239a8de10c18365bde7062d8959b7ed525449c561Douglas GregorA3<g> *a14_7; // expected-error{{non-type template argument of type '<overloaded function type>' cannot be converted to a value of type 'int (*)(int)'}}
63a35284bba5db7a6179d70fcce8fbe66481058698Douglas Gregor// FIXME: the first error includes the string <overloaded function
64a35284bba5db7a6179d70fcce8fbe66481058698Douglas Gregor// type>, which makes Doug slightly unhappy.
65f684e6e793a336f52138a2609b207e6eef3c3022Douglas Gregor
66f684e6e793a336f52138a2609b207e6eef3c3022Douglas Gregor
67f684e6e793a336f52138a2609b207e6eef3c3022Douglas Gregorstruct Y { } y;
68f684e6e793a336f52138a2609b207e6eef3c3022Douglas Gregor
69f684e6e793a336f52138a2609b207e6eef3c3022Douglas Gregorvolatile X * X_volatile_ptr;
70f684e6e793a336f52138a2609b207e6eef3c3022Douglas Gregortemplate<X const &AnX> struct A4; // expected-note 2{{template parameter is declared here}}
71cc45cb3630b42c5245e26593e385097c220bc859Douglas GregorA4<an_X> *a15_1; // okay
7239a8de10c18365bde7062d8959b7ed525449c561Douglas GregorA4<*X_volatile_ptr> *a15_2; // expected-error{{reference binding of non-type template parameter of type 'class X const &' to template argument of type 'class X volatile' ignores qualifiers}}
7339a8de10c18365bde7062d8959b7ed525449c561Douglas GregorA4<y> *15_3; //  expected-error{{non-type template parameter of reference type 'class X const &' cannot bind to template argument of type 'struct Y'}} \
7439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor            // FIXME: expected-error{{expected unqualified-id}}
75f684e6e793a336f52138a2609b207e6eef3c3022Douglas Gregor
76b86b0579c5805c8ecaedd2d676e06bf8c2bf7f79Douglas Gregortemplate<int (&fr)(int)> struct A5; // expected-note 2{{template parameter is declared here}}
77b86b0579c5805c8ecaedd2d676e06bf8c2bf7f79Douglas GregorA5<h> *a16_1;
78b86b0579c5805c8ecaedd2d676e06bf8c2bf7f79Douglas GregorA5<f> *a16_3;
7939a8de10c18365bde7062d8959b7ed525449c561Douglas GregorA5<h2> *a16_6;  // expected-error{{non-type template argument of type 'float (float)' cannot be converted to a value of type 'int (&)(int)'}}
8039a8de10c18365bde7062d8959b7ed525449c561Douglas GregorA5<g> *a14_7; // expected-error{{non-type template argument of type '<overloaded function type>' cannot be converted to a value of type 'int (&)(int)'}}
81b86b0579c5805c8ecaedd2d676e06bf8c2bf7f79Douglas Gregor// FIXME: the first error includes the string <overloaded function
82b86b0579c5805c8ecaedd2d676e06bf8c2bf7f79Douglas Gregor// type>, which makes Doug slightly unhappy.
83b86b0579c5805c8ecaedd2d676e06bf8c2bf7f79Douglas Gregor
84b86b0579c5805c8ecaedd2d676e06bf8c2bf7f79Douglas Gregorstruct Z {
85b86b0579c5805c8ecaedd2d676e06bf8c2bf7f79Douglas Gregor  int foo(int);
86b86b0579c5805c8ecaedd2d676e06bf8c2bf7f79Douglas Gregor  float bar(float);
87b86b0579c5805c8ecaedd2d676e06bf8c2bf7f79Douglas Gregor  int bar(int);
88b86b0579c5805c8ecaedd2d676e06bf8c2bf7f79Douglas Gregor  double baz(double);
89658bbb5e8072ccd68b5ddc299d1b868aa047a746Douglas Gregor
90658bbb5e8072ccd68b5ddc299d1b868aa047a746Douglas Gregor  int int_member;
91658bbb5e8072ccd68b5ddc299d1b868aa047a746Douglas Gregor  float float_member;
92b86b0579c5805c8ecaedd2d676e06bf8c2bf7f79Douglas Gregor};
93b86b0579c5805c8ecaedd2d676e06bf8c2bf7f79Douglas Gregortemplate<int (Z::*pmf)(int)> struct A6; // expected-note{{template parameter is declared here}}
94b86b0579c5805c8ecaedd2d676e06bf8c2bf7f79Douglas GregorA6<&Z::foo> *a17_1;
95b86b0579c5805c8ecaedd2d676e06bf8c2bf7f79Douglas GregorA6<&Z::bar> *a17_2;
9639a8de10c18365bde7062d8959b7ed525449c561Douglas GregorA6<&Z::baz> *a17_3; // expected-error{{non-type template argument of type 'double (struct Z::*)(double)' cannot be converted to a value of type 'int (struct Z::*)(int)'}}
97658bbb5e8072ccd68b5ddc299d1b868aa047a746Douglas Gregor
98658bbb5e8072ccd68b5ddc299d1b868aa047a746Douglas Gregor
99658bbb5e8072ccd68b5ddc299d1b868aa047a746Douglas Gregortemplate<int Z::*pm> struct A7;  // expected-note{{template parameter is declared here}}
100658bbb5e8072ccd68b5ddc299d1b868aa047a746Douglas Gregortemplate<int Z::*pm> struct A7c;
101658bbb5e8072ccd68b5ddc299d1b868aa047a746Douglas GregorA7<&Z::int_member> *a18_1;
102658bbb5e8072ccd68b5ddc299d1b868aa047a746Douglas GregorA7c<&Z::int_member> *a18_2;
10339a8de10c18365bde7062d8959b7ed525449c561Douglas GregorA7<&Z::float_member> *a18_3; // expected-error{{non-type template argument of type 'float struct Z::*' cannot be converted to a value of type 'int struct Z::*'}}
10439a8de10c18365bde7062d8959b7ed525449c561Douglas GregorA7c<(&Z::int_member)> *a18_3; // expected-error{{non-type template argument cannot be surrounded by parentheses}}
105