brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.0 KiB · 904f950 Raw
257 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %s2// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s3// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s4 5 6// This test creates cases where implicit instantiations of various entities7// would cause a diagnostic, but provides expliict specializations for those8// entities that avoid the diagnostic. The specializations are alternately9// declarations and definitions, and the intent of this test is to verify10// that we allow specializations only in the appropriate namespaces (and11// nowhere else).12struct NonDefaultConstructible {13  NonDefaultConstructible(int);14};15 16 17// C++ [temp.expl.spec]p1:18//   An explicit specialization of any of the following:19 20//     -- function template21namespace N0 {22  template<typename T> void f0(T) {23    T t;24  }25 26  template<> void f0(NonDefaultConstructible) { }27 28  void test_f0(NonDefaultConstructible NDC) {29    f0(NDC);30  }31  32  template<> void f0(int);33  template<> void f0(long);34}35 36template<> void N0::f0(int) { } // okay37 38namespace N1 {39  template<> void N0::f0(long) { } // expected-error{{does not enclose namespace}}40}41 42template<> void N0::f0(double);43 44template<> void N0::f0(double) { }45 46struct X1 {47  template<typename T> void f(T);48  49  template<> void f(int);50};51 52//     -- class template53namespace N0 {54  55template<typename T>56struct X0 { // expected-note {{explicitly specialized declaration is here}}57  static T member;58  59  void f1(T t) {60    t = 17;61  }62  63  struct Inner : public T { }; // expected-note 2{{explicitly specialized declaration is here}}64  65  template<typename U>66  struct InnerTemplate : public T { }; // expected-note {{explicitly specialized declaration is here}}67  // expected-error@-1 {{base specifier must name a class}}68  69  template<typename U>70  void ft1(T t, U u);71};72 73}74 75template<typename T> 76template<typename U>77void N0::X0<T>::ft1(T t, U u) {78  t = u;79}80 81template<typename T> T N0::X0<T>::member;82 83template<> struct N0::X0<void> { };84N0::X0<void> test_X0;85 86namespace N1 {87  template<> struct N0::X0<const void> { }; // expected-error{{not in a namespace enclosing 'N0'}}88}89 90namespace N0 {91  template<> struct X0<volatile void>;92}93 94template<> struct N0::X0<volatile void> { 95  void f1(void *);96};97 98//     -- member function of a class template99template<> void N0::X0<void*>::f1(void *) { }100 101void test_spec(N0::X0<void*> xvp, void *vp) {102  xvp.f1(vp);103}104 105namespace N0 {106  template<> void X0<volatile void>::f1(void *) { } // expected-error{{no function template matches}}107 108  template<> void X0<const volatile void*>::f1(const volatile void*);109}110 111void test_x0_cvvoid(N0::X0<const volatile void*> x0, const volatile void *cvp) {112  x0.f1(cvp); // okay: we've explicitly specialized113}114 115//     -- static data member of a class template116namespace N0 {117  // This actually tests p15; the following is a declaration, not a definition.118  template<> 119  NonDefaultConstructible X0<NonDefaultConstructible>::member;120  121  template<> long X0<long>::member = 17;122 123  template<> float X0<float>::member;124  125  template<> double X0<double>::member;126}127 128NonDefaultConstructible &get_static_member() {129  return N0::X0<NonDefaultConstructible>::member;130}131 132template<> int N0::X0<int>::member;133 134template<> float N0::X0<float>::member = 3.14f;135 136namespace N1 {137  template<> double N0::X0<double>::member = 3.14; // expected-error{{does not enclose namespace}}138}139 140//    -- member class of a class template141namespace N0 {142  143  template<>144  struct X0<void*>::Inner { };145 146  template<>147  struct X0<int>::Inner { };148 149  template<>150  struct X0<unsigned>::Inner;151 152  template<>153  struct X0<float>::Inner;154 155  template<>156  struct X0<double>::Inner; // expected-note{{forward declaration}}157}158 159template<>160struct N0::X0<long>::Inner { };161 162template<>163struct N0::X0<float>::Inner { };164 165namespace N1 {166  template<>167  struct N0::X0<unsigned>::Inner { }; // expected-error{{member class specialization}}168 169  template<>170  struct N0::X0<unsigned long>::Inner { }; // expected-error{{member class specialization}}171};172 173N0::X0<void*>::Inner inner0;174N0::X0<int>::Inner inner1;175N0::X0<long>::Inner inner2;176N0::X0<float>::Inner inner3;177N0::X0<double>::Inner inner4; // expected-error{{incomplete}}178 179//    -- member class template of a class template180namespace N0 {181  template<>182  template<>183  struct X0<void*>::InnerTemplate<int> { };184  185  template<> template<>186  struct X0<int>::InnerTemplate<int>; // expected-note{{forward declaration}}187 188  template<> template<>189  struct X0<int>::InnerTemplate<long>;190 191  template<> template<>192  struct X0<int>::InnerTemplate<double>;193}194 195template<> template<>196struct N0::X0<int>::InnerTemplate<long> { }; // okay197 198template<> template<>199struct N0::X0<int>::InnerTemplate<float> { };200 201namespace N1 {202  template<> template<>203  struct N0::X0<int>::InnerTemplate<double> { }; // expected-error{{enclosing}}204}205 206N0::X0<void*>::InnerTemplate<int> inner_template0;207N0::X0<int>::InnerTemplate<int> inner_template1; // expected-error{{incomplete}}208N0::X0<int>::InnerTemplate<long> inner_template2;209N0::X0<int>::InnerTemplate<unsigned long> inner_template3; // expected-note{{instantiation}}210 211//    -- member function template of a class template212namespace N0 {213  template<>214  template<>215  void X0<void*>::ft1(void*, const void*) { }216  217  template<> template<>218  void X0<void*>::ft1(void *, int);219 220  template<> template<>221  void X0<void*>::ft1(void *, unsigned);222 223  template<> template<>224  void X0<void*>::ft1(void *, long);225}226 227template<> template<>228void N0::X0<void*>::ft1(void *, unsigned) { } // okay229 230template<> template<>231void N0::X0<void*>::ft1(void *, float) { }232 233namespace N1 {234  template<> template<>235  void N0::X0<void*>::ft1(void *, long) { } // expected-error{{does not enclose namespace}}236}237 238 239void test_func_template(N0::X0<void *> xvp, void *vp, const void *cvp,240                        int i, unsigned u) {241  xvp.ft1(vp, cvp);242  xvp.ft1(vp, i);243  xvp.ft1(vp, u);244}245 246namespace PR8979 {247  template<typename Z>248  struct X0 {249    template <class T, class U> class Inner;250    struct OtherInner;251    template<typename T, typename U> void f(Inner<T, U>&);252 253    typedef Inner<OtherInner, OtherInner> MyInner;254    template<> void f(MyInner&);255  };256}257