ms-if-exists.cpp 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. // RUN: %clang_cc1 -fms-extensions -std=c++11 %s -verify
  2. struct Nontemplate {
  3. typedef int type;
  4. };
  5. template<typename T>
  6. struct X {
  7. __if_exists(Nontemplate::type) {
  8. typedef Nontemplate::type type;
  9. }
  10. __if_exists(Nontemplate::value) {
  11. typedef Nontemplate::value type2;
  12. }
  13. __if_not_exists(Nontemplate::value) {
  14. typedef int type3;
  15. }
  16. __if_exists(T::X) { // expected-warning{{dependent __if_exists declarations are ignored}}
  17. typedef T::X type4;
  18. }
  19. };
  20. X<int>::type i1;
  21. X<int>::type2 i2; // expected-error{{no type named 'type2' in 'X<int>'}}
  22. X<int>::type3 i3;
  23. X<int>::type4 i4; // expected-error{{no type named 'type4' in 'X<int>'}}
  24. struct HasFoo {
  25. void foo();
  26. };
  27. struct HasBar {
  28. void bar(int);
  29. void bar(float);
  30. };
  31. template<typename T>
  32. void f(T t) {
  33. __if_exists(T::foo) {
  34. { }
  35. t.foo();
  36. }
  37. __if_not_exists(T::bar) {
  38. int *i = t; // expected-error{{no viable conversion from 'HasFoo' to 'int *'}}
  39. { }
  40. }
  41. int array2[] = {
  42. 0,
  43. __if_exists(T::bar) {2, }// expected-warning{{dependent __if_exists declarations are ignored}}
  44. 3
  45. };
  46. }
  47. template void f(HasFoo); // expected-note{{in instantiation of function template specialization 'f<HasFoo>' requested here}}
  48. template void f(HasBar);
  49. template<typename T, typename ...Ts>
  50. void g(T, Ts...) {
  51. __if_exists(T::operator Ts) { // expected-error{{__if_exists name contains unexpanded parameter pack 'Ts'}}
  52. }
  53. __if_not_exists(Ts::operator T) { // expected-error{{__if_not_exists name contains unexpanded parameter pack 'Ts'}}
  54. }
  55. }