// RUN: clang-cc -fsyntax-only -std=c++98 -verify %s template struct A; // expected-note 5{{template parameter is declared here}} A<0> *a0; A *a1; // expected-error{{template argument for non-type template parameter is treated as type 'int ()'}} A *a2; // expected-error{{template argument for non-type template parameter must be an expression}} A<1 >> 2> *a3; // expected-warning{{use of right-shift operator ('>>') in template argument will require parentheses in C++0x}} // C++ [temp.arg.nontype]p5: A *a4; // expected-error{{must be an expression}} enum E { Enumerator = 17 }; A *a5; // expected-error{{template argument for non-type template parameter must be an expression}} template struct A1; // expected-note{{template parameter is declared here}} A1 *a6; // okay A1<17> *a7; // expected-error{{non-type template argument of type 'int' cannot be converted to a value of type 'enum E'}} const long LongValue = 12345678; A *a8; const short ShortValue = 17; A *a9; int f(int); A *a10; // expected-error{{non-type template argument of type 'int' is not an integral constant expression}} class X { public: X(); X(int, int); operator int() const; }; A *a11; // expected-error{{non-type template argument of type 'class X' must have an integral or enumeration type}} template struct A2; X *X_ptr; X an_X; X array_of_Xs[10]; A2 *a12; A2 *a13; A2<&an_X> *a13_2; A2<(&an_X)> *a13_3; // expected-error{{non-type template argument cannot be surrounded by parentheses}} float f(float); float g(float); double g(double); int h(int); float h2(float); template struct A3; // expected-note 2{{template parameter is declared here}} A3 *a14_1; A3<&h> *a14_2; A3 *a14_3; A3<&f> *a14_4; A3

*a14_6; // expected-error{{non-type template argument of type 'float (*)(float)' cannot be converted to a value of type 'int (*)(int)'}} A3 *a14_7; // expected-error{{non-type template argument of type '' cannot be converted to a value of type 'int (*)(int)'}} // FIXME: the first error includes the string , which makes Doug slightly unhappy. struct Y { } y; volatile X * X_volatile_ptr; template struct A4; // expected-note 2{{template parameter is declared here}} A4 *a15_1; // okay A4<*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}} A4 *15_3; // expected-error{{non-type template parameter of reference type 'class X const &' cannot bind to template argument of type 'struct Y'}} \ // FIXME: expected-error{{expected unqualified-id}} template struct A5; // expected-note 2{{template parameter is declared here}} A5 *a16_1; A5 *a16_3; A5

*a16_6; // expected-error{{non-type template argument of type 'float (float)' cannot be converted to a value of type 'int (&)(int)'}} A5 *a14_7; // expected-error{{non-type template argument of type '' cannot be converted to a value of type 'int (&)(int)'}} // FIXME: the first error includes the string , which makes Doug slightly unhappy. struct Z { int foo(int); float bar(float); int bar(int); double baz(double); int int_member; float float_member; }; template struct A6; // expected-note{{template parameter is declared here}} A6<&Z::foo> *a17_1; A6<&Z::bar> *a17_2; A6<&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)'}} template struct A7; // expected-note{{template parameter is declared here}} template struct A7c; A7<&Z::int_member> *a18_1; A7c<&Z::int_member> *a18_2; A7<&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::*'}} A7c<(&Z::int_member)> *a18_3; // expected-error{{non-type template argument cannot be surrounded by parentheses}} template struct Overflow; // expected-note{{template parameter is declared here}} Overflow<5> *overflow1; // okay Overflow<256> *overflow2; // expected-error{{non-type template argument value '256' is too large for template parameter of type 'unsigned char'}} template struct Signedness; // expected-note{{template parameter is declared here}} Signedness<10> *signedness1; // okay Signedness<-10> *signedness2; // expected-error{{non-type template argument provides negative value '-10' for unsigned template parameter of type 'unsigned int'}} // Check canonicalization of template arguments. template struct FuncPtr0; int func0(int, int); extern FuncPtr0<&func0> *fp0; template struct FuncPtr0; extern FuncPtr0<&func0> *fp0; int func0(int, int); extern FuncPtr0<&func0> *fp0; // PR5350 namespace ns { template struct Foo { static const bool value = true; }; template struct Bar {}; const bool value = false; Bar::value)> x; } // PR5349 namespace ns { enum E { k }; template struct Baz {}; Baz f1; // This works. Baz f2; // This too. Baz(0)> f3; // And this. Baz b1; // This doesn't work. Baz(0)> b2; // This neither. }