// RUN: %clang_cc1 -std=c++11 -verify %s namespace std_example { template struct A { ~A() = delete; }; // expected-note {{deleted here}} template auto h() -> A; template auto i(T) -> T; template auto f(T) -> decltype(i(h())); // #1 template auto f(T) -> void; // #2 auto g() -> void { f(42); // ok, calls #2, since #1 is not viable. } template auto q(T) -> decltype((h())); void r() { // Deduction against q succeeds, but results in a temporary which can't be // destroyed. q(42); // expected-error {{attempt to use a deleted function}} } } class PD { friend struct A; ~PD(); // expected-note 5{{here}} public: typedef int n; }; struct DD { ~DD() = delete; // expected-note 2{{here}} typedef int n; }; PD pd(); DD dd(); struct A { decltype(pd()) s; // ok decltype(pd())::n n; // ok decltype(dd()) *p = new decltype(dd()); // ok }; A a(); // Two errors here: one for the decltype, one for the variable. decltype( pd(), // expected-error {{private destructor}} pd()) pd1; // expected-error {{private destructor}} decltype(dd(), // expected-error {{deleted function}} dd()) dd1; decltype(a(), dd()) dd2; // expected-error {{deleted function}} decltype( pd(), // expected-error {{temporary of type 'PD' has private destructor}} 0) pd2; decltype(((13, ((dd())))))::n dd_parens; // ok decltype(((((42)), pd())))::n pd_parens_comma; // ok // Ensure parens aren't stripped from a decltype node. extern decltype(pd()) pd_ref; // ok decltype((pd_ref)) pd_ref3 = pd_ref; // ok, PD & decltype(pd_ref) pd_ref2 = pd_ref; // expected-error {{private destructor}} namespace libcxx_example { struct nat { nat() = delete; nat(const nat&) = delete; nat &operator=(const nat&) = delete; ~nat() = delete; }; struct any { any(...); }; template struct is_same { static const bool value = false; }; template struct is_same { static const bool value = true; }; template T declval(); void swap(int &a, int &b); nat swap(any, any); template struct swappable { typedef decltype(swap(declval(), declval())) type; static const bool value = !is_same::value; constexpr operator bool() const { return value; } }; static_assert(swappable(), ""); static_assert(!swappable(), ""); } namespace RequireCompleteType { template struct S { static_assert(OK, "boom!"); // expected-error 2{{boom!}} }; template T make(); template S make(); void consume(...); decltype(make<0, false>()) *p1; // ok decltype((make<1, false>())) *p2; // ok // A complete type is required here in order to detect an overloaded 'operator,'. decltype(123, make<2, false>()) *p3; // expected-note {{here}} decltype(consume(make<3, false>())) *p4; // expected-note {{here}} decltype(make())>()) *p5; // ok } namespace Overload { DD operator+(PD &a, PD &b); decltype(pd()) *pd_ptr; decltype(*pd_ptr + *pd_ptr) *dd_ptr; // ok decltype(0, *pd_ptr) pd_ref2 = pd_ref; // ok DD operator,(int a, PD b); decltype(0, *pd_ptr) *dd_ptr2; // expected-error {{private destructor}} }