aboutsummaryrefslogtreecommitdiff
path: root/test/SemaTemplate
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2009-11-18 14:59:57 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2009-11-18 14:59:57 +0000
commitb3d5a323a5ca92ea73443499cee2f15db1ff0fb3 (patch)
tree60a1694bec5a44d15456acc880cb2f91619f66aa /test/SemaTemplate
parent8f57cb0305232cb53fff00ef151ca716766f3437 (diff)
downloadsrc-b3d5a323a5ca92ea73443499cee2f15db1ff0fb3.tar.gz
src-b3d5a323a5ca92ea73443499cee2f15db1ff0fb3.zip
Update clang to r89205.
Notes
Notes: svn path=/vendor/clang/dist/; revision=199482
Diffstat (limited to 'test/SemaTemplate')
-rw-r--r--test/SemaTemplate/class-template-decl.cpp8
-rw-r--r--test/SemaTemplate/class-template-spec.cpp7
-rw-r--r--test/SemaTemplate/constructor-template.cpp32
-rw-r--r--test/SemaTemplate/deduction.cpp83
-rw-r--r--test/SemaTemplate/default-arguments.cpp81
-rw-r--r--test/SemaTemplate/default-expr-arguments.cpp40
-rw-r--r--test/SemaTemplate/enum-argument.cpp16
-rw-r--r--test/SemaTemplate/example-dynarray.cpp2
-rw-r--r--test/SemaTemplate/instantiate-attr.cpp7
-rw-r--r--test/SemaTemplate/instantiate-decl-init.cpp22
-rw-r--r--test/SemaTemplate/instantiate-member-pointers.cpp30
-rw-r--r--test/SemaTemplate/instantiate-member-template.cpp13
-rw-r--r--test/SemaTemplate/instantiate-overloaded-arrow.cpp20
-rw-r--r--test/SemaTemplate/instantiate-template-template-parm.cpp27
-rw-r--r--test/SemaTemplate/instantiate-using-decl.cpp3
-rw-r--r--test/SemaTemplate/instantiation-default-2.cpp2
-rw-r--r--test/SemaTemplate/member-function-template.cpp24
-rw-r--r--test/SemaTemplate/nested-name-spec-template.cpp17
-rw-r--r--test/SemaTemplate/nested-template.cpp18
-rw-r--r--test/SemaTemplate/operator-template.cpp2
-rw-r--r--test/SemaTemplate/temp_arg_nontype.cpp3
-rw-r--r--test/SemaTemplate/temp_arg_template.cpp7
-rw-r--r--test/SemaTemplate/value-dependent-null-pointer-constant.cpp2
23 files changed, 431 insertions, 35 deletions
diff --git a/test/SemaTemplate/class-template-decl.cpp b/test/SemaTemplate/class-template-decl.cpp
index d2e90c1daa8f..a8163127b000 100644
--- a/test/SemaTemplate/class-template-decl.cpp
+++ b/test/SemaTemplate/class-template-decl.cpp
@@ -41,15 +41,13 @@ struct test {}; // expected-note{{previous definition}}
template<typename T>
struct test : T {}; // expected-error{{redefinition}}
-#if 0
-// FIXME: parse template declarations in these scopes, so that we can
-// complain about the one at function scope.
class X {
public:
template<typename T> class C;
};
void f() {
- template<typename T> class X;
+ template<typename T> class X; // expected-error{{expression}}
}
-#endif
+
+template<typename T> class X1 { } var; // expected-error{{declared as a template}}
diff --git a/test/SemaTemplate/class-template-spec.cpp b/test/SemaTemplate/class-template-spec.cpp
index 4cd43b469ae0..2808404b1d99 100644
--- a/test/SemaTemplate/class-template-spec.cpp
+++ b/test/SemaTemplate/class-template-spec.cpp
@@ -19,7 +19,7 @@ int test_specs(A<float, float> *a1, A<float, int> *a2) {
int test_incomplete_specs(A<double, double> *a1,
A<double> *a2)
{
- (void)a1->x; // expected-error{{incomplete definition of type 'A<double, double>'}}
+ (void)a1->x; // expected-error{{member access into incomplete type}}
(void)a2->x; // expected-error{{implicit instantiation of undefined template 'struct A<double, int>'}}
}
@@ -104,3 +104,8 @@ Foo<int>* v;
Foo<int>& F() { return *v; }
template <typename T> class Foo {};
Foo<int> x;
+
+
+// Template template parameters
+template<template<class T> class Wibble>
+class Wibble<int> { }; // expected-error{{cannot specialize a template template parameter}}
diff --git a/test/SemaTemplate/constructor-template.cpp b/test/SemaTemplate/constructor-template.cpp
index 79bf7c585e34..12c6f8b9c101 100644
--- a/test/SemaTemplate/constructor-template.cpp
+++ b/test/SemaTemplate/constructor-template.cpp
@@ -1,5 +1,4 @@
// RUN: clang-cc -fsyntax-only -verify %s
-
struct X0 { // expected-note{{candidate}}
X0(int); // expected-note{{candidate}}
template<typename T> X0(T);
@@ -52,3 +51,34 @@ template<class C> struct A {};
template <> struct A<int>{A(const A<int>&);};
struct B { A<int> x; B(B& a) : x(a.x) {} };
+struct X2 {
+ X2();
+ X2(X2&);
+ template<typename T> X2(T);
+};
+
+X2 test(bool Cond, X2 x2) {
+ if (Cond)
+ return x2; // okay, uses copy constructor
+
+ return X2(); // expected-error{{incompatible type}}
+}
+
+struct X3 {
+ template<typename T> X3(T);
+};
+
+template<> X3::X3(X3); // expected-error{{must pass its first argument by reference}}
+
+struct X4 {
+ X4();
+ ~X4();
+ X4(X4&);
+ template<typename T> X4(const T&, int = 17);
+};
+
+X4 test_X4(bool Cond, X4 x4) {
+ X4 a(x4, 17); // okay, constructor template
+ X4 b(x4); // okay, copy constructor
+ return X4(); // expected-error{{incompatible type}}
+}
diff --git a/test/SemaTemplate/deduction.cpp b/test/SemaTemplate/deduction.cpp
new file mode 100644
index 000000000000..7b7e18f74aec
--- /dev/null
+++ b/test/SemaTemplate/deduction.cpp
@@ -0,0 +1,83 @@
+// RUN: clang-cc -fsyntax-only %s
+
+// Template argument deduction with template template parameters.
+template<typename T, template<T> class A>
+struct X0 {
+ static const unsigned value = 0;
+};
+
+template<template<int> class A>
+struct X0<int, A> {
+ static const unsigned value = 1;
+};
+
+template<int> struct X0i;
+template<long> struct X0l;
+int array_x0a[X0<long, X0l>::value == 0? 1 : -1];
+int array_x0b[X0<int, X0i>::value == 1? 1 : -1];
+
+template<typename T, typename U>
+struct is_same {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+ static const bool value = true;
+};
+
+template<typename T> struct allocator { };
+template<typename T, typename Alloc = allocator<T> > struct vector {};
+
+// Fun with meta-lambdas!
+struct _1 {};
+struct _2 {};
+
+// Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T.
+template<typename T, typename Arg1, typename Arg2>
+struct Replace {
+ typedef T type;
+};
+
+// Replacement of the whole type.
+template<typename Arg1, typename Arg2>
+struct Replace<_1, Arg1, Arg2> {
+ typedef Arg1 type;
+};
+
+template<typename Arg1, typename Arg2>
+struct Replace<_2, Arg1, Arg2> {
+ typedef Arg2 type;
+};
+
+// Replacement through cv-qualifiers
+template<typename T, typename Arg1, typename Arg2>
+struct Replace<const T, Arg1, Arg2> {
+ typedef typename Replace<T, Arg1, Arg2>::type const type;
+};
+
+// Replacement of templates
+template<template<typename> class TT, typename T1, typename Arg1, typename Arg2>
+struct Replace<TT<T1>, Arg1, Arg2> {
+ typedef TT<typename Replace<T1, Arg1, Arg2>::type> type;
+};
+
+template<template<typename, typename> class TT, typename T1, typename T2,
+ typename Arg1, typename Arg2>
+struct Replace<TT<T1, T2>, Arg1, Arg2> {
+ typedef TT<typename Replace<T1, Arg1, Arg2>::type,
+ typename Replace<T2, Arg1, Arg2>::type> type;
+};
+
+// Just for kicks...
+template<template<typename, typename> class TT, typename T1,
+ typename Arg1, typename Arg2>
+struct Replace<TT<T1, _2>, Arg1, Arg2> {
+ typedef TT<typename Replace<T1, Arg1, Arg2>::type, Arg2> type;
+};
+
+int array0[is_same<Replace<_1, int, float>::type, int>::value? 1 : -1];
+int array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -1];
+int array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1];
+int array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1];
+int array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1];
diff --git a/test/SemaTemplate/default-arguments.cpp b/test/SemaTemplate/default-arguments.cpp
index 33677aab73ac..0247ddc0ef28 100644
--- a/test/SemaTemplate/default-arguments.cpp
+++ b/test/SemaTemplate/default-arguments.cpp
@@ -1,5 +1,4 @@
// RUN: clang-cc -fsyntax-only -verify %s
-
template<typename T, int N = 2> struct X; // expected-note{{template is declared here}}
X<int, 1> *x1;
@@ -42,3 +41,83 @@ template<>
struct B<void> {
typedef B<void*> type;
};
+
+// Nested default arguments for template parameters.
+template<typename T> struct X1 { };
+
+template<typename T>
+struct X2 {
+ template<typename U = typename X1<T>::type> // expected-error{{no type named}}
+ struct Inner1 { };
+
+ template<T Value = X1<T>::value> // expected-error{{no member named 'value'}}
+ struct NonType1 { };
+
+ template<T Value>
+ struct Inner2 { };
+
+ template<typename U>
+ struct Inner3 {
+ template<typename X = T, typename V = U>
+ struct VeryInner { };
+
+ template<T Value1 = sizeof(T), T Value2 = sizeof(U),
+ T Value3 = Value1 + Value2>
+ struct NonType2 { };
+ };
+};
+
+X2<int> x2i;
+X2<int>::Inner1<float> x2iif;
+
+X2<int>::Inner1<> x2bad; // expected-note{{instantiation of default argument}}
+
+X2<int>::NonType1<'a'> x2_nontype1;
+X2<int>::NonType1<> x2_nontype1_bad; // expected-note{{instantiation of default argument}}
+
+// Check multi-level substitution into template type arguments
+X2<int>::Inner3<float>::VeryInner<> vi;
+X2<char>::Inner3<int>::NonType2<> x2_deep_nontype;
+
+template<typename T, typename U>
+struct is_same { static const bool value = false; };
+
+template<typename T>
+struct is_same<T, T> { static const bool value = true; };
+
+int array1[is_same<__typeof__(vi),
+ X2<int>::Inner3<float>::VeryInner<int, float> >::value? 1 : -1];
+
+int array2[is_same<__typeof(x2_deep_nontype),
+ X2<char>::Inner3<int>::NonType2<sizeof(char), sizeof(int),
+ sizeof(char)+sizeof(int)> >::value? 1 : -1];
+
+// Template template parameter defaults
+template<template<typename T> class X = X2> struct X3 { };
+int array3[is_same<X3<>, X3<X2> >::value? 1 : -1];
+
+struct add_pointer {
+ template<typename T>
+ struct apply {
+ typedef T* type;
+ };
+};
+
+template<typename T, template<typename> class X = T::template apply>
+ struct X4;
+int array4[is_same<X4<add_pointer>,
+ X4<add_pointer, add_pointer::apply> >::value? 1 : -1];
+
+template<int> struct X5 {}; // expected-note{{has a different type 'int'}}
+template<long> struct X5b {};
+template<typename T,
+ template<T> class B = X5> // expected-error{{template template argument has different}} \
+ // expected-note{{previous non-type template parameter}}
+ struct X6 {};
+
+X6<int> x6a;
+X6<long> x6b; // expected-note{{while checking a default template argument}}
+X6<long, X5b> x6c;
+
+
+template<template<class> class X = B<int> > struct X7; // expected-error{{must be a class template}}
diff --git a/test/SemaTemplate/default-expr-arguments.cpp b/test/SemaTemplate/default-expr-arguments.cpp
index 9c0f1ecf0c3b..34ac2d967efc 100644
--- a/test/SemaTemplate/default-expr-arguments.cpp
+++ b/test/SemaTemplate/default-expr-arguments.cpp
@@ -65,8 +65,8 @@ void test_x0(X0<int> xi) {
xi.f(17);
}
-struct NotDefaultConstructible { // expected-note{{candidate}}
- NotDefaultConstructible(int); // expected-note{{candidate}}
+struct NotDefaultConstructible { // expected-note 2{{candidate}}
+ NotDefaultConstructible(int); // expected-note 2{{candidate}}
};
void test_x0_not_default_constructible(X0<NotDefaultConstructible> xn) {
@@ -85,6 +85,18 @@ void test_X1() {
X1<int> x1;
}
+template<typename T>
+struct X2 {
+ void operator()(T = T()); // expected-error{{no matching}}
+};
+
+void test_x2(X2<int> x2i, X2<NotDefaultConstructible> x2n) {
+ x2i();
+ x2i(17);
+ x2n(NotDefaultConstructible(17));
+ x2n(); // expected-note{{in instantiation of default function argument}}
+}
+
// PR5283
namespace PR5283 {
template<typename T> struct A {
@@ -108,3 +120,27 @@ struct D {
};
D::D() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}}
}
+
+// PR5301
+namespace pr5301 {
+ void f(int, int = 0);
+
+ template <typename T>
+ void g(T, T = 0);
+
+ template <int I>
+ void i(int a = I);
+
+ template <typename T>
+ void h(T t) {
+ f(0);
+ g(1);
+ g(t);
+ i<2>();
+ }
+
+ void test() {
+ h(0);
+ }
+}
+
diff --git a/test/SemaTemplate/enum-argument.cpp b/test/SemaTemplate/enum-argument.cpp
index 101a1d0cd9da..1d782df202e3 100644
--- a/test/SemaTemplate/enum-argument.cpp
+++ b/test/SemaTemplate/enum-argument.cpp
@@ -5,3 +5,19 @@ template <Enum v> struct C {
typedef C<v> Self;
};
template struct C<val>;
+
+template<typename T>
+struct get_size {
+ static const unsigned value = sizeof(T);
+};
+
+template<typename T>
+struct X0 {
+ enum {
+ Val1 = get_size<T>::value,
+ Val2,
+ SumOfValues = Val1 + Val2
+ };
+};
+
+X0<int> x0i;
diff --git a/test/SemaTemplate/example-dynarray.cpp b/test/SemaTemplate/example-dynarray.cpp
index 2b752b4f1f49..6f3e58e32ab6 100644
--- a/test/SemaTemplate/example-dynarray.cpp
+++ b/test/SemaTemplate/example-dynarray.cpp
@@ -1,4 +1,4 @@
-// RUN: clang-cc -emit-llvm-only %s
+// RUN: clang -emit-llvm -S -o %t %s
#include <stddef.h>
#include <stdlib.h>
#include <assert.h>
diff --git a/test/SemaTemplate/instantiate-attr.cpp b/test/SemaTemplate/instantiate-attr.cpp
new file mode 100644
index 000000000000..08ba9c3a0cd5
--- /dev/null
+++ b/test/SemaTemplate/instantiate-attr.cpp
@@ -0,0 +1,7 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+template <typename T>
+struct A {
+ char a __attribute__((aligned(16)));
+};
+int a[sizeof(A<int>) == 16 ? 1 : -1];
+
diff --git a/test/SemaTemplate/instantiate-decl-init.cpp b/test/SemaTemplate/instantiate-decl-init.cpp
new file mode 100644
index 000000000000..d957f2de7da5
--- /dev/null
+++ b/test/SemaTemplate/instantiate-decl-init.cpp
@@ -0,0 +1,22 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+// PR5426 - the non-dependent obj would be fully processed and wrapped in a
+// CXXConstructExpr at definition time, which would lead to a failure at
+// instantiation time.
+struct arg {
+ arg();
+};
+
+struct oldstylemove {
+ oldstylemove(oldstylemove&);
+ oldstylemove(const arg&);
+};
+
+template <typename T>
+void fn(T t, const arg& arg) {
+ oldstylemove obj(arg);
+}
+
+void test() {
+ fn(1, arg());
+}
diff --git a/test/SemaTemplate/instantiate-member-pointers.cpp b/test/SemaTemplate/instantiate-member-pointers.cpp
index b3ddb3fafa31..d2c9e6b5ed82 100644
--- a/test/SemaTemplate/instantiate-member-pointers.cpp
+++ b/test/SemaTemplate/instantiate-member-pointers.cpp
@@ -1,5 +1,4 @@
// RUN: clang-cc -fsyntax-only -verify %s
-
struct Y {
int x;
};
@@ -25,3 +24,32 @@ struct X2 {
template struct X2<int, Y>;
template struct X2<int&, Y>; // expected-note{{instantiation}}
template struct X2<const void, Y>; // expected-note{{instantiation}}
+
+template<typename T, typename Class, T Class::*Ptr>
+struct X3 {
+ X3<T, Class, Ptr> &operator=(const T& value) {
+ return *this;
+ }
+};
+
+X3<int, Y, &Y::x> x3;
+
+typedef int Y::*IntMember;
+
+template<IntMember Member>
+struct X4 {
+ X3<int, Y, Member> member;
+
+ int &getMember(Y& y) { return y.*Member; }
+};
+
+int &get_X4(X4<&Y::x> x4, Y& y) {
+ return x4.getMember(y);
+}
+
+template<IntMember Member>
+void accept_X4(X4<Member>);
+
+void test_accept_X4(X4<&Y::x> x4) {
+ accept_X4(x4);
+}
diff --git a/test/SemaTemplate/instantiate-member-template.cpp b/test/SemaTemplate/instantiate-member-template.cpp
index 36f3b6fd490d..95556bcc221b 100644
--- a/test/SemaTemplate/instantiate-member-template.cpp
+++ b/test/SemaTemplate/instantiate-member-template.cpp
@@ -103,3 +103,16 @@ void test_X1(int *ip, int i, double *dp) {
X1<int*>::Inner4<int>::value = 17;
i = X1<int*>::Inner4<int&>::value; // expected-note{{instantiation}}
}
+
+
+template<typename T>
+struct X2 {
+ template<T *Ptr> // expected-error{{pointer to a reference}}
+ struct Inner;
+
+ template<T Value> // expected-error{{cannot have type 'float'}}
+ struct Inner2;
+};
+
+X2<int&> x2a; // expected-note{{instantiation}}
+X2<float> x2b; // expected-note{{instantiation}}
diff --git a/test/SemaTemplate/instantiate-overloaded-arrow.cpp b/test/SemaTemplate/instantiate-overloaded-arrow.cpp
new file mode 100644
index 000000000000..7f0ef0c990ad
--- /dev/null
+++ b/test/SemaTemplate/instantiate-overloaded-arrow.cpp
@@ -0,0 +1,20 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+// PR5488
+
+struct X {
+ int x;
+};
+
+struct Iter {
+ X* operator->();
+};
+
+template <typename T>
+void Foo() {
+ (void)Iter()->x;
+}
+
+void Func() {
+ Foo<int>();
+}
+
diff --git a/test/SemaTemplate/instantiate-template-template-parm.cpp b/test/SemaTemplate/instantiate-template-template-parm.cpp
index b158251915a0..30ba113e20d4 100644
--- a/test/SemaTemplate/instantiate-template-template-parm.cpp
+++ b/test/SemaTemplate/instantiate-template-template-parm.cpp
@@ -1,5 +1,4 @@
// RUN: clang-cc -fsyntax-only -verify %s
-
template<template<typename T> class MetaFun, typename Value>
struct apply {
typedef typename MetaFun<Value>::type type;
@@ -19,3 +18,29 @@ int i;
apply<add_pointer, int>::type ip = &i;
apply<add_reference, int>::type ir = i;
apply<add_reference, float>::type fr = i; // expected-error{{non-const lvalue reference to type 'float' cannot be initialized with a value of type 'int'}}
+
+// Template template parameters
+template<int> struct B; // expected-note{{has a different type 'int'}}
+
+template<typename T,
+ template<T Value> class X> // expected-error{{cannot have type 'float'}} \
+ // expected-note{{with type 'long'}}
+struct X0 { };
+
+X0<int, B> x0b1;
+X0<float, B> x0b2; // expected-note{{while substituting}}
+X0<long, B> x0b3; // expected-error{{template template argument has different template parameters}}
+
+template<template<int V> class TT> // expected-note{{parameter with type 'int'}}
+struct X1 { };
+
+template<typename T, template<T V> class TT>
+struct X2 {
+ X1<TT> x1; // expected-error{{has different template parameters}}
+};
+
+template<int V> struct X3i { };
+template<long V> struct X3l { }; // expected-note{{different type 'long'}}
+
+X2<int, X3i> x2okay;
+X2<long, X3l> x2bad; // expected-note{{instantiation}}
diff --git a/test/SemaTemplate/instantiate-using-decl.cpp b/test/SemaTemplate/instantiate-using-decl.cpp
index fd9010fa4bbb..a1cf355c890e 100644
--- a/test/SemaTemplate/instantiate-using-decl.cpp
+++ b/test/SemaTemplate/instantiate-using-decl.cpp
@@ -1,5 +1,7 @@
// RUN: clang-cc -fsyntax-only -verify %s
+namespace N { }
+
template<typename T>
struct A {
void f();
@@ -10,6 +12,7 @@ struct B : A<T> {
using A<T>::f;
void g() {
+ using namespace N;
f();
}
};
diff --git a/test/SemaTemplate/instantiation-default-2.cpp b/test/SemaTemplate/instantiation-default-2.cpp
index 740832c5ba39..4d9a0e2717bf 100644
--- a/test/SemaTemplate/instantiation-default-2.cpp
+++ b/test/SemaTemplate/instantiation-default-2.cpp
@@ -15,4 +15,4 @@ Constant<float (*)(int, double), &f> *c5;
Constant<float (*)(int, int), f> *c6; // expected-error{{non-type template argument of type 'float (*)(int, double)' cannot be converted to a value of type 'float (*)(int, int)'}}
-Constant<float, 0> *c7; // expected-note{{in instantiation of default argument for 'Constant<float>' required here}}
+Constant<float, 0> *c7; // expected-note{{while substituting}}
diff --git a/test/SemaTemplate/member-function-template.cpp b/test/SemaTemplate/member-function-template.cpp
index 83bf16c69004..1d46d31e35d3 100644
--- a/test/SemaTemplate/member-function-template.cpp
+++ b/test/SemaTemplate/member-function-template.cpp
@@ -49,3 +49,27 @@ void test_X_f0_explicit(X x, int i, long l) {
// PR4608
class A { template <class x> x a(x z) { return z+y; } int y; };
+// PR5419
+struct Functor {
+ template <typename T>
+ bool operator()(const T& v) const {
+ return true;
+ }
+};
+
+void test_Functor(Functor f) {
+ f(1);
+}
+
+// Instantiation on ->
+template<typename T>
+struct X1 {
+ template<typename U> U& get();
+};
+
+template<typename T> struct X2; // expected-note{{here}}
+
+void test_incomplete_access(X1<int> *x1, X2<int> *x2) {
+ float &fr = x1->get<float>();
+ (void)x2->get<float>(); // expected-error{{implicit instantiation of undefined template}}
+}
diff --git a/test/SemaTemplate/nested-name-spec-template.cpp b/test/SemaTemplate/nested-name-spec-template.cpp
index 1bdc7a89d4e8..e936640f5e3e 100644
--- a/test/SemaTemplate/nested-name-spec-template.cpp
+++ b/test/SemaTemplate/nested-name-spec-template.cpp
@@ -28,11 +28,8 @@ N::M::Promote<int>::type *ret_intptr5(int* ip) { return ip; }
::N::M::Promote<int>::type *ret_intptr6(int* ip) { return ip; }
-N::M::template; // expected-error{{expected template name after 'template' keyword in nested name specifier}} \
- // expected-error{{expected unqualified-id}}
-
-N::M::template Promote; // expected-error{{expected '<' after 'template Promote' in nested name specifier}} \
-// expected-error{{C++ requires a type specifier for all declarations}}
+N::M::template; // expected-error{{expected unqualified-id}}
+N::M::template Promote; // expected-error{{expected unqualified-id}}
namespace N {
template<typename T> struct A;
@@ -49,13 +46,9 @@ struct ::N::A<int>::X {
int foo;
};
-#if 0
-// FIXME: the following crashes the parser, because Sema has no way to
-// communicate that the "dependent" template-name N::template B doesn't
-// actually refer to a template.
template<typename T>
struct TestA {
- typedef typename N::template B<T>::type type; // xpected-error{{'B' following the 'template' keyword does not refer to a template}}
- // FIXME: should show what B *does* refer to.
+ typedef typename N::template B<T>::type type; // expected-error{{'B' following the 'template' keyword does not refer to a template}} \
+ // expected-error{{identifier or template-id}} \
+ // expected-error{{expected member name}}
};
-#endif
diff --git a/test/SemaTemplate/nested-template.cpp b/test/SemaTemplate/nested-template.cpp
index 4d948184cee9..e18329c145d0 100644
--- a/test/SemaTemplate/nested-template.cpp
+++ b/test/SemaTemplate/nested-template.cpp
@@ -108,3 +108,21 @@ struct X1 {
template<typename, bool = false> struct B { };
};
template struct X1<int>::B<bool>;
+
+// Template template parameters
+template<typename T>
+struct X2 {
+ template<template<class U, T Value> class> // expected-error{{cannot have type 'float'}} \
+ // expected-note{{previous non-type template}}
+ struct Inner { };
+};
+
+template<typename T,
+ int Value> // expected-note{{template non-type parameter}}
+ struct X2_arg;
+
+X2<int>::Inner<X2_arg> x2i1;
+X2<float> x2a; // expected-note{{instantiation}}
+X2<long>::Inner<X2_arg> x2i3; // expected-error{{template template argument has different}}
+
+
diff --git a/test/SemaTemplate/operator-template.cpp b/test/SemaTemplate/operator-template.cpp
index 7039e0ec83de..dc44d04b6882 100644
--- a/test/SemaTemplate/operator-template.cpp
+++ b/test/SemaTemplate/operator-template.cpp
@@ -11,6 +11,6 @@ int a0(A<int> x) { return x == 1; }
template<class X>struct B{typedef X Y;};
template<class X>bool operator==(B<X>*,typename B<X>::Y); // \
expected-error{{overloaded 'operator==' must have at least one parameter of class or enumeration type}} \
-expected-note{{in instantiation of member function}}
+expected-note{{in instantiation of function template specialization}}
int a(B<int> x) { return operator==(&x,1); }
diff --git a/test/SemaTemplate/temp_arg_nontype.cpp b/test/SemaTemplate/temp_arg_nontype.cpp
index a6611582f170..bde92be93dfb 100644
--- a/test/SemaTemplate/temp_arg_nontype.cpp
+++ b/test/SemaTemplate/temp_arg_nontype.cpp
@@ -10,8 +10,7 @@ A<int> *a2; // expected-error{{template argument for non-type template parameter
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<A> *a4; // expected-error{{must have an integral or enumeration type}} \
- // FIXME: the error message above is a bit lame
+A<A> *a4; // expected-error{{must be an expression}}
enum E { Enumerator = 17 };
A<E> *a5; // expected-error{{template argument for non-type template parameter must be an expression}}
diff --git a/test/SemaTemplate/temp_arg_template.cpp b/test/SemaTemplate/temp_arg_template.cpp
index f2ee66b3f731..ada244bb5de6 100644
--- a/test/SemaTemplate/temp_arg_template.cpp
+++ b/test/SemaTemplate/temp_arg_template.cpp
@@ -26,12 +26,9 @@ B<X> *a6; // expected-error{{template template argument has different template p
C<Y> *a7;
C<Ylong> *a8; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
-template<typename T> void f(int); // expected-note{{function template}}
+template<typename T> void f(int);
-// FIXME: we're right to provide an error message, but it should say
-// that we need a class template. We won't get this right until name
-// lookup of 'f' returns a TemplateDecl.
-A<f> *a9; // expected-error{{template argument does not refer to}}
+A<f> *a9; // expected-error{{must be a class template}}
// FIXME: The code below is ill-formed, because of the evil digraph '<:'.
// We should provide a much better error message than we currently do.
diff --git a/test/SemaTemplate/value-dependent-null-pointer-constant.cpp b/test/SemaTemplate/value-dependent-null-pointer-constant.cpp
index 8bde1277edd5..110c380c9aa2 100644
--- a/test/SemaTemplate/value-dependent-null-pointer-constant.cpp
+++ b/test/SemaTemplate/value-dependent-null-pointer-constant.cpp
@@ -26,4 +26,4 @@ struct A { };
template <typename T> void f(T *t)
{
(void)static_cast<void*>(static_cast<A*>(t));
-} \ No newline at end of file
+}