class-template-spec.cpp revision 8e0c118cb6c22c448ce502f3e00d01630192f095
14adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao// RUN: %clang_cc1 -fsyntax-only -verify %s 24adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaotemplate<typename T, typename U = int> struct A; // expected-note {{template is declared here}} \ 34adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao // expected-note{{explicitly specialized}} 44adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 54adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaotemplate<> struct A<double, double>; // expected-note{{forward declaration}} 6 7template<> struct A<float, float> { // expected-note{{previous definition}} 8 int x; 9}; 10 11template<> struct A<float> { // expected-note{{previous definition}} 12 int y; 13}; 14 15int test_specs(A<float, float> *a1, A<float, int> *a2) { 16 return a1->x + a2->y; 17} 18 19int 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 26typedef float FLOAT; 27 28template<> struct A<float, FLOAT>; 29 30template<> struct A<FLOAT, float> { }; // expected-error{{redefinition}} 31 32template<> struct A<float, int> { }; // expected-error{{redefinition}} 33 34template<typename T, typename U = int> struct X; 35 36template <> struct X<int, int> { int foo(); }; // #1 37template <> struct X<float> { int bar(); }; // #2 38 39typedef int int_type; 40void 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. 46template<> 47struct A<char> { 48 A(); 49}; 50 51A<char>::A() { } 52 53// Make sure we can see specializations defined before the primary template. 54namespace N{ 55 template<typename T> struct A0; 56} 57 58namespace N { 59 template<> 60 struct A0<void> { 61 typedef void* pointer; 62 }; 63} 64 65namespace N { 66 template<typename T> 67 struct A0 { 68 void foo(A0<void>::pointer p = 0); 69 }; 70} 71 72// Diagnose specialization errors 73struct A<double> { }; // expected-error{{template specialization requires 'template<>'}} 74 75template<> struct ::A<double>; 76 77namespace 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 87template<> struct N::B<int> { }; // okay 88 89template<> struct N::B<float> { }; // expected-warning{{originally}} 90 91namespace 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 97template<> struct N::B<char> { 98 int testf(int x) { return f(x); } 99}; 100 101// PR5264 102template <typename T> class Foo; 103Foo<int>* v; 104Foo<int>& F() { return *v; } 105template <typename T> class Foo {}; 106Foo<int> x; 107 108 109// Template template parameters 110template<template<class T> class Wibble> 111class Wibble<int> { }; // expected-error{{cannot specialize a template template parameter}} 112 113namespace rdar9676205 { 114 template<typename T> 115 struct X { 116 template<typename U> 117 struct X<U*> { // expected-error{{explicit specialization of 'X' in class scope}} 118 }; 119 }; 120 121} 122