165019acfc46ffb191fac4e781ac0c4b8d0c8434eDouglas Gregor// RUN: %clang_cc1 -fms-extensions -std=c++11 %s -verify
23896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor
33896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregorstruct Nontemplate {
43896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  typedef int type;
53896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor};
63896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor
73896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregortemplate<typename T>
83896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregorstruct X {
93896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  __if_exists(Nontemplate::type) {
103896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    typedef Nontemplate::type type;
113896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  }
123896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor
133896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  __if_exists(Nontemplate::value) {
143896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    typedef Nontemplate::value type2;
153896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  }
163896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor
173896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  __if_not_exists(Nontemplate::value) {
183896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    typedef int type3;
193896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  }
203896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor
213896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  __if_exists(T::X) { // expected-warning{{dependent __if_exists declarations are ignored}}
223896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    typedef T::X type4;
233896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  }
243896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor};
253896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor
263896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas GregorX<int>::type i1;
273896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas GregorX<int>::type2 i2; // expected-error{{no type named 'type2' in 'X<int>'}}
283896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas GregorX<int>::type3 i3;
293896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas GregorX<int>::type4 i4; // expected-error{{no type named 'type4' in 'X<int>'}}
303896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor
313896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregorstruct HasFoo {
323896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  void foo();
333896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor};
343896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregorstruct HasBar {
353896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  void bar(int);
363896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  void bar(float);
373896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor};
383896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor
393896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregortemplate<typename T>
403896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregorvoid f(T t) {
413896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  __if_exists(T::foo) {
423896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    { }
433896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    t.foo();
443896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  }
453896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor
463896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  __if_not_exists(T::bar) {
47ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor    int *i = t; // expected-error{{no viable conversion from 'HasFoo' to 'int *'}}
483896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    { }
493896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  }
509d24a8be93b28488dbfb9bbe8aa6fe35b21a5b0cFrancois Pichet
51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int array2[] = {
52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    0,
53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    __if_exists(T::bar) {2, }// expected-warning{{dependent __if_exists declarations are ignored}}
54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    3
55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  };
563896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor}
573896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor
58ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregortemplate void f(HasFoo); // expected-note{{in instantiation of function template specialization 'f<HasFoo>' requested here}}
593896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregortemplate void f(HasBar);
6065019acfc46ffb191fac4e781ac0c4b8d0c8434eDouglas Gregor
6165019acfc46ffb191fac4e781ac0c4b8d0c8434eDouglas Gregortemplate<typename T, typename ...Ts>
6265019acfc46ffb191fac4e781ac0c4b8d0c8434eDouglas Gregorvoid g(T, Ts...) {
6365019acfc46ffb191fac4e781ac0c4b8d0c8434eDouglas Gregor  __if_exists(T::operator Ts) { // expected-error{{__if_exists name contains unexpanded parameter pack 'Ts'}}
6465019acfc46ffb191fac4e781ac0c4b8d0c8434eDouglas Gregor  }
6565019acfc46ffb191fac4e781ac0c4b8d0c8434eDouglas Gregor
6665019acfc46ffb191fac4e781ac0c4b8d0c8434eDouglas Gregor  __if_not_exists(Ts::operator T) { // expected-error{{__if_not_exists name contains unexpanded parameter pack 'Ts'}}
6765019acfc46ffb191fac4e781ac0c4b8d0c8434eDouglas Gregor  }
6865019acfc46ffb191fac4e781ac0c4b8d0c8434eDouglas Gregor}
69