17e010a04fef171049291d8cb3047f118566da090Douglas Gregor// RUN: %clang_cc1 -verify %s
28e8fb3be5bd78f0564444eca02b404566a5f3b5dAndy Gibbs// expected-no-diagnostics
3cca9e9674a5e50a283185d8e9d8a5c3414eb008eDouglas Gregor
4cca9e9674a5e50a283185d8e9d8a5c3414eb008eDouglas Gregortypedef char one_byte;
5cca9e9674a5e50a283185d8e9d8a5c3414eb008eDouglas Gregorstruct two_bytes { char data[2]; };
6cca9e9674a5e50a283185d8e9d8a5c3414eb008eDouglas Gregor
7cca9e9674a5e50a283185d8e9d8a5c3414eb008eDouglas Gregortemplate<typename T> one_byte __is_class_check(int T::*);
8cca9e9674a5e50a283185d8e9d8a5c3414eb008eDouglas Gregortemplate<typename T> two_bytes __is_class_check(...);
9cca9e9674a5e50a283185d8e9d8a5c3414eb008eDouglas Gregor
10cca9e9674a5e50a283185d8e9d8a5c3414eb008eDouglas Gregortemplate<typename T> struct is_class {
11cca9e9674a5e50a283185d8e9d8a5c3414eb008eDouglas Gregor  static const bool value = sizeof(__is_class_check<T>(0)) == 1;
12cca9e9674a5e50a283185d8e9d8a5c3414eb008eDouglas Gregor};
13cca9e9674a5e50a283185d8e9d8a5c3414eb008eDouglas Gregor
14cca9e9674a5e50a283185d8e9d8a5c3414eb008eDouglas Gregorstruct X { };
15cca9e9674a5e50a283185d8e9d8a5c3414eb008eDouglas Gregor
16cca9e9674a5e50a283185d8e9d8a5c3414eb008eDouglas Gregorint array0[is_class<X>::value? 1 : -1];
17cca9e9674a5e50a283185d8e9d8a5c3414eb008eDouglas Gregorint array1[is_class<int>::value? -1 : 1];
18cca9e9674a5e50a283185d8e9d8a5c3414eb008eDouglas Gregorint array2[is_class<char[3]>::value? -1 : 1];
197e010a04fef171049291d8cb3047f118566da090Douglas Gregor
207e010a04fef171049291d8cb3047f118566da090Douglas Gregornamespace instantiation_order1 {
217e010a04fef171049291d8cb3047f118566da090Douglas Gregor  template<typename T>
227e010a04fef171049291d8cb3047f118566da090Douglas Gregor  struct it_is_a_trap {
237e010a04fef171049291d8cb3047f118566da090Douglas Gregor    typedef typename T::trap type;
247e010a04fef171049291d8cb3047f118566da090Douglas Gregor  };
257e010a04fef171049291d8cb3047f118566da090Douglas Gregor
267e010a04fef171049291d8cb3047f118566da090Douglas Gregor  template<bool, typename T = void>
277e010a04fef171049291d8cb3047f118566da090Douglas Gregor  struct enable_if {
287e010a04fef171049291d8cb3047f118566da090Douglas Gregor    typedef T type;
297e010a04fef171049291d8cb3047f118566da090Douglas Gregor  };
307e010a04fef171049291d8cb3047f118566da090Douglas Gregor
317e010a04fef171049291d8cb3047f118566da090Douglas Gregor  template<typename T>
327e010a04fef171049291d8cb3047f118566da090Douglas Gregor  struct enable_if<false, T> { };
337e010a04fef171049291d8cb3047f118566da090Douglas Gregor
347e010a04fef171049291d8cb3047f118566da090Douglas Gregor  template<typename T>
357e010a04fef171049291d8cb3047f118566da090Douglas Gregor  typename enable_if<sizeof(T) == 17>::type
367e010a04fef171049291d8cb3047f118566da090Douglas Gregor  f(const T&, typename it_is_a_trap<T>::type* = 0);
377e010a04fef171049291d8cb3047f118566da090Douglas Gregor
387e010a04fef171049291d8cb3047f118566da090Douglas Gregor  void f(...);
397e010a04fef171049291d8cb3047f118566da090Douglas Gregor
407e010a04fef171049291d8cb3047f118566da090Douglas Gregor  void test_f() {
417e010a04fef171049291d8cb3047f118566da090Douglas Gregor    f('a');
427e010a04fef171049291d8cb3047f118566da090Douglas Gregor  }
437e010a04fef171049291d8cb3047f118566da090Douglas Gregor}
44