15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RUN: %clang_cc1 -std=c++11 -verify %s
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace std_example {
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class T> struct A { ~A() = delete; }; // expected-note {{deleted here}}
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class T> auto h() -> A<T>;
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class T> auto i(T) -> T;
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class T> auto f(T) -> decltype(i(h<T>())); // #1
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class T> auto f(T) -> void; // #2
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)auto g() -> void {
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  f(42); // ok, calls #2, since #1 is not viable.
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class T> auto q(T) -> decltype((h<T>()));
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void r() {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Deduction against q succeeds, but results in a temporary which can't be
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // destroyed.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  q(42); // expected-error {{attempt to use a deleted function}}
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PD {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend struct A;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~PD(); // expected-note 5{{here}}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef int n;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct DD {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~DD() = delete; // expected-note 2{{here}}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef int n;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct A {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  decltype(PD()) s; // ok
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  decltype(PD())::n n; // ok
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  decltype(DD()) *p = new decltype(DD()); // ok
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Two errors here: one for the decltype, one for the variable.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)decltype(
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PD(), // expected-error {{private destructor}}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PD()) pd1; // expected-error {{private destructor}}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)decltype(DD(), // expected-error {{deleted function}}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         DD()) dd1;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)decltype(A(),
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         DD()) dd2; // expected-error {{deleted function}}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)decltype(
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PD(), // expected-error {{temporary of type 'PD' has private destructor}}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0) pd2;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)decltype(((13, ((DD())))))::n dd_parens; // ok
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)decltype(((((42)), PD())))::n pd_parens_comma; // ok
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure parens aren't stripped from a decltype node.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern decltype(PD()) pd_ref; // ok
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)decltype((pd_ref)) pd_ref3 = pd_ref; // ok, PD &
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)decltype(pd_ref) pd_ref2 = pd_ref; // expected-error {{private destructor}}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace libcxx_example {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct nat {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nat() = delete;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nat(const nat&) = delete;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nat &operator=(const nat&) = delete;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~nat() = delete;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct any {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    any(...);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename T, typename U> struct is_same { static const bool value = false; };
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename T> struct is_same<T, T> { static const bool value = true; };
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename T> T declval();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void swap(int &a, int &b);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nat swap(any, any);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename T> struct swappable {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef decltype(swap(declval<T&>(), declval<T&>())) type;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static const bool value = !is_same<type, nat>::value;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    constexpr operator bool() const { return value; }
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static_assert(swappable<int>(), "");
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static_assert(!swappable<const int>(), "");
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace RequireCompleteType {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<int N, bool OK> struct S {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static_assert(OK, "boom!"); // expected-error 2{{boom!}}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename T> T make();
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<int N, bool OK> S<N, OK> make();
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void consume(...);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  decltype(make<0, false>()) *p1; // ok
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  decltype((make<1, false>())) *p2; // ok
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A complete type is required here in order to detect an overloaded 'operator,'.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  decltype(123, make<2, false>()) *p3; // expected-note {{here}}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  decltype(consume(make<3, false>())) *p4; // expected-note {{here}}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  decltype(make<decltype(make<4, false>())>()) *p5; // ok
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace Overload {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DD operator+(PD &a, PD &b);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  decltype(PD()) *pd_ptr;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  decltype(*pd_ptr + *pd_ptr) *dd_ptr; // ok
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  decltype(0, *pd_ptr) pd_ref2 = pd_ref; // ok
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DD operator,(int a, PD b);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  decltype(0, *pd_ptr) *dd_ptr2; // expected-error {{private destructor}}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)