temp_explicit.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wc++11-compat %s
  2. //
  3. // Tests explicit instantiation of templates.
  4. template<typename T, typename U = T> class X0 { };
  5. namespace N {
  6. template<typename T, typename U = T> class X1 { };
  7. }
  8. // Check the syntax of explicit instantiations.
  9. template class X0<int, float>;
  10. template class X0<int>; // expected-note{{previous}}
  11. template class N::X1<int>;
  12. template class ::N::X1<int, float>;
  13. using namespace N;
  14. // Check for some bogus syntax that probably means that the user
  15. // wanted to write an explicit specialization, but forgot the '<>'
  16. // after 'template'.
  17. template class X0<double> { }; // expected-error{{explicit specialization}}
  18. // Check for explicit instantiations that come after other kinds of
  19. // instantiations or declarations.
  20. template class X0<int, int>; // expected-error{{duplicate}}
  21. template<> class X0<char> { }; // expected-note{{previous}}
  22. template class X0<char>; // expected-warning{{ignored}}
  23. void foo(X0<short>) { }
  24. template class X0<short>;
  25. // Check that explicit instantiations actually produce definitions. We
  26. // determine whether this happens by placing semantic errors in the
  27. // definition of the template we're instantiating.
  28. template<typename T> struct X2; // expected-note{{declared here}}
  29. template struct X2<float>; // expected-error{{undefined template}}
  30. template<typename T>
  31. struct X2 {
  32. void f0(T*); // expected-error{{pointer to a reference}}
  33. };
  34. template struct X2<int>; // okay
  35. template struct X2<int&>; // expected-note{{in instantiation of}}
  36. // Check that explicit instantiations instantiate member classes.
  37. template<typename T> struct X3 {
  38. struct Inner {
  39. void f(T*); // expected-error{{pointer to a reference}}
  40. };
  41. };
  42. void f1(X3<int&>); // okay, Inner, not instantiated
  43. template struct X3<int&>; // expected-note{{instantiation}}
  44. template<typename T> struct X4 {
  45. struct Inner {
  46. struct VeryInner {
  47. void f(T*); // expected-error 2{{pointer to a reference}}
  48. };
  49. };
  50. };
  51. void f2(X4<int&>); // okay, Inner, not instantiated
  52. void f3(X4<int&>::Inner); // okay, Inner::VeryInner, not instantiated
  53. template struct X4<int&>; // expected-note{{instantiation}}
  54. template struct X4<float&>; // expected-note{{instantiation}}
  55. // Check explicit instantiation of member classes
  56. namespace N2 {
  57. template<typename T>
  58. struct X5 {
  59. struct Inner1 {
  60. void f(T&);
  61. };
  62. struct Inner2 { // expected-note {{here}}
  63. struct VeryInner {
  64. void g(T*); // expected-error 2{{pointer to a reference}}
  65. };
  66. };
  67. };
  68. }
  69. template struct N2::X5<void>::Inner2;
  70. using namespace N2;
  71. template struct X5<int&>::Inner2; // expected-note{{instantiation}}
  72. void f4(X5<float&>::Inner2);
  73. template struct X5<float&>::Inner2; // expected-note{{instantiation}}
  74. namespace N3 {
  75. template struct N2::X5<int>::Inner2; // expected-warning {{explicit instantiation of 'Inner2' not in a namespace enclosing 'N2'}}
  76. }
  77. struct X6 {
  78. struct Inner { // expected-note{{here}}
  79. void f();
  80. };
  81. };
  82. template struct X6::Inner; // expected-error{{non-templated}}
  83. // PR5559
  84. template <typename T>
  85. struct Foo;
  86. template <>
  87. struct Foo<int> // expected-note{{header not required for explicitly-specialized}}
  88. {
  89. template <typename U>
  90. struct Bar
  91. {};
  92. };
  93. template <> // expected-warning{{extraneous template parameter list}}
  94. template <>
  95. struct Foo<int>::Bar<void>
  96. {};
  97. namespace N1 {
  98. template<typename T> struct X7 { }; // expected-note{{here}}
  99. namespace Inner {
  100. template<typename T> struct X8 { };
  101. }
  102. template struct X7<int>;
  103. template struct Inner::X8<int>;
  104. }
  105. template<typename T> struct X9 { }; // expected-note{{here}}
  106. template struct ::N1::Inner::X8<float>;
  107. namespace N2 {
  108. using namespace N1;
  109. template struct X7<double>; // expected-warning{{must occur in namespace}}
  110. template struct X9<float>; // expected-warning{{must occur at global scope}}
  111. }