template-id-expr.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // RUN: %clang_cc1 -fsyntax-only -verify %s
  2. // PR5336
  3. template<typename FromCl>
  4. struct isa_impl_cl {
  5. template<class ToCl>
  6. static void isa(const FromCl &Val) { }
  7. };
  8. template<class X, class Y>
  9. void isa(const Y &Val) { return isa_impl_cl<Y>::template isa<X>(Val); }
  10. class Value;
  11. void f0(const Value &Val) { isa<Value>(Val); }
  12. // Implicit template-ids.
  13. template<typename T>
  14. struct X0 {
  15. template<typename U>
  16. void f1();
  17. template<typename U>
  18. void f2(U) {
  19. f1<U>();
  20. }
  21. };
  22. void test_X0_int(X0<int> xi, float f) {
  23. xi.f2(f);
  24. }
  25. // Not template-id expressions, but they almost look like it.
  26. template<typename F>
  27. struct Y {
  28. Y(const F&);
  29. };
  30. template<int I>
  31. struct X {
  32. X(int, int);
  33. void f() {
  34. Y<X<I> >(X<I>(0, 0));
  35. Y<X<I> >(::X<I>(0, 0));
  36. }
  37. };
  38. template struct X<3>;
  39. // 'template' as a disambiguator.
  40. // PR7030
  41. struct Y0 {
  42. template<typename U>
  43. void f1(U);
  44. template<typename U>
  45. static void f2(U);
  46. void f3(int);
  47. static int f4(int);
  48. template<typename U>
  49. static void f4(U);
  50. template<typename U>
  51. void f() {
  52. Y0::template f1<U>(0);
  53. Y0::template f1(0);
  54. this->template f1(0);
  55. Y0::template f2<U>(0);
  56. Y0::template f2(0);
  57. Y0::template f3(0); // expected-error {{'f3' following the 'template' keyword does not refer to a template}}
  58. Y0::template f3(); // expected-error {{'f3' following the 'template' keyword does not refer to a template}}
  59. int x;
  60. x = Y0::f4(0);
  61. x = Y0::f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
  62. x = Y0::template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
  63. x = this->f4(0);
  64. x = this->f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
  65. x = this->template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
  66. }
  67. };
  68. struct A {
  69. template<int I>
  70. struct B {
  71. static void b1();
  72. };
  73. };
  74. template<int I>
  75. void f5() {
  76. A::template B<I>::template b1(); // expected-error {{'b1' following the 'template' keyword does not refer to a template}}
  77. }
  78. template void f5<0>(); // expected-note {{in instantiation of function template specialization 'f5<0>' requested here}}