1 // RUN: %clang_cc1 -fsyntax-only -verify %s 2 template<typename T, typename U = int> struct A; // expected-note {{template is declared here}} \ 3 // expected-note{{explicitly specialized}} 4 5 template<> struct A<double, double>; // expected-note{{forward declaration}} 6 7 template<> struct A<float, float> { // expected-note{{previous definition}} 8 int x; 9 }; 10 11 template<> struct A<float> { // expected-note{{previous definition}} 12 int y; 13 }; 14 15 int test_specs(A<float, float> *a1, A<float, int> *a2) { 16 return a1->x + a2->y; 17 } 18 19 int test_incomplete_specs(A<double, double> *a1, 20 A<double> *a2) 21 { 22 (void)a1->x; // expected-error{{member access into incomplete type}} 23 (void)a2->x; // expected-error{{implicit instantiation of undefined template 'A<double, int>'}} 24 } 25 26 typedef float FLOAT; 27 28 template<> struct A<float, FLOAT>; 29 30 template<> struct A<FLOAT, float> { }; // expected-error{{redefinition}} 31 32 template<> struct A<float, int> { }; // expected-error{{redefinition}} 33 34 template<typename T, typename U = int> struct X; 35 36 template <> struct X<int, int> { int foo(); }; // #1 37 template <> struct X<float> { int bar(); }; // #2 38 39 typedef int int_type; 40 void testme(X<int_type> *x1, X<float, int> *x2) { 41 (void)x1->foo(); // okay: refers to #1 42 (void)x2->bar(); // okay: refers to #2 43 } 44 45 // Make sure specializations are proper classes. 46 template<> 47 struct A<char> { 48 A(); 49 }; 50 51 A<char>::A() { } 52 53 // Make sure we can see specializations defined before the primary template. 54 namespace N{ 55 template<typename T> struct A0; 56 } 57 58 namespace N { 59 template<> 60 struct A0<void> { 61 typedef void* pointer; 62 }; 63 } 64 65 namespace N { 66 template<typename T> 67 struct A0 { 68 void foo(A0<void>::pointer p = 0); 69 }; 70 } 71 72 // Diagnose specialization errors 73 struct A<double> { }; // expected-error{{template specialization requires 'template<>'}} 74 75 template<> struct ::A<double>; 76 77 namespace N { 78 template<typename T> struct B; // expected-note 2{{explicitly specialized}} 79 80 template<> struct ::N::B<char>; // okay 81 template<> struct ::N::B<short>; // okay 82 template<> struct ::N::B<int>; // okay 83 84 int f(int); 85 } 86 87 template<> struct N::B<int> { }; // okay 88 89 template<> struct N::B<float> { }; // expected-warning{{originally}} 90 91 namespace M { 92 template<> struct ::N::B<short> { }; // expected-error{{class template specialization of 'B' not in a namespace enclosing 'N'}} 93 94 template<> struct ::A<long double>; // expected-error{{originally}} 95 } 96 97 template<> struct N::B<char> { 98 int testf(int x) { return f(x); } 99 }; 100 101 // PR5264 102 template <typename T> class Foo; 103 Foo<int>* v; 104 Foo<int>& F() { return *v; } 105 template <typename T> class Foo {}; 106 Foo<int> x; 107 108 109 // Template template parameters 110 template<template<class T> class Wibble> 111 class Wibble<int> { }; // expected-error{{cannot specialize a template template parameter}} 112