member-access-expr.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // RUN: %clang_cc1 -fsyntax-only -verify %s
  2. template<typename T>
  3. void call_f0(T x) {
  4. x.Base::f0();
  5. }
  6. struct Base {
  7. void f0();
  8. };
  9. struct X0 : Base {
  10. typedef Base CrazyBase;
  11. };
  12. void test_f0(X0 x0) {
  13. call_f0(x0);
  14. }
  15. template<typename TheBase, typename T>
  16. void call_f0_through_typedef(T x) {
  17. typedef TheBase Base2;
  18. x.Base2::f0();
  19. }
  20. void test_f0_through_typedef(X0 x0) {
  21. call_f0_through_typedef<Base>(x0);
  22. }
  23. template<typename TheBase, typename T>
  24. void call_f0_through_typedef2(T x) {
  25. typedef TheBase CrazyBase; // expected-note{{current scope}}
  26. x.CrazyBase::f0(); // expected-error{{ambiguous}} \
  27. // expected-error 2{{no member named}}
  28. }
  29. struct OtherBase { };
  30. struct X1 : Base, OtherBase {
  31. typedef OtherBase CrazyBase; // expected-note{{object type}}
  32. };
  33. void test_f0_through_typedef2(X0 x0, X1 x1) {
  34. call_f0_through_typedef2<Base>(x0);
  35. call_f0_through_typedef2<OtherBase>(x1); // expected-note{{instantiation}}
  36. call_f0_through_typedef2<Base>(x1); // expected-note{{instantiation}}
  37. }
  38. struct X2 {
  39. operator int() const;
  40. };
  41. template<typename T, typename U>
  42. T convert(const U& value) {
  43. return value.operator T(); // expected-error{{operator long}}
  44. }
  45. void test_convert(X2 x2) {
  46. convert<int>(x2);
  47. convert<long>(x2); // expected-note{{instantiation}}
  48. }
  49. template<typename T>
  50. void destruct(T* ptr) {
  51. ptr->~T();
  52. ptr->T::~T();
  53. }
  54. template<typename T>
  55. void destruct_intptr(int *ip) {
  56. ip->~T();
  57. ip->T::~T();
  58. }
  59. void test_destruct(X2 *x2p, int *ip) {
  60. destruct(x2p);
  61. destruct(ip);
  62. destruct_intptr<int>(ip);
  63. }
  64. // PR5220
  65. class X3 {
  66. protected:
  67. template <int> float* &f0();
  68. template <int> const float* &f0() const;
  69. void f1() {
  70. (void)static_cast<float*>(f0<0>());
  71. }
  72. void f1() const{
  73. (void)f0<0>();
  74. }
  75. };
  76. // Fun with template instantiation and conversions
  77. struct X4 {
  78. int& member();
  79. float& member() const;
  80. };
  81. template<typename T>
  82. struct X5 {
  83. void f(T* ptr) { int& ir = ptr->member(); }
  84. void g(T* ptr) { float& fr = ptr->member(); }
  85. };
  86. void test_X5(X5<X4> x5, X5<const X4> x5c, X4 *xp, const X4 *cxp) {
  87. x5.f(xp);
  88. x5c.g(cxp);
  89. }
  90. // In theory we can do overload resolution at template-definition time on this.
  91. // We should at least not assert.
  92. namespace test4 {
  93. struct Base {
  94. template <class T> void foo() {}
  95. };
  96. template <class T> struct Foo : Base {
  97. void test() {
  98. foo<int>();
  99. }
  100. };
  101. }
  102. namespace test5 {
  103. template<typename T>
  104. struct X {
  105. using T::value;
  106. T &getValue() {
  107. return &value;
  108. }
  109. };
  110. }
  111. // PR8739
  112. namespace test6 {
  113. struct A {};
  114. struct B {};
  115. template <class T> class Base;
  116. template <class T> class Derived : public Base<T> {
  117. A *field;
  118. void get(B **ptr) {
  119. // It's okay if at some point we figure out how to diagnose this
  120. // at instantiation time.
  121. *ptr = field;
  122. }
  123. };
  124. }