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