176f3f69db1416425070177243e9f390122c553e0Richard Smith// RUN: %clang_cc1 -std=c++11 -verify %s
276f3f69db1416425070177243e9f390122c553e0Richard Smith
376f3f69db1416425070177243e9f390122c553e0Richard Smithnamespace std_example {
476f3f69db1416425070177243e9f390122c553e0Richard Smith
576f3f69db1416425070177243e9f390122c553e0Richard Smithtemplate<class T> struct A { ~A() = delete; }; // expected-note {{deleted here}}
676f3f69db1416425070177243e9f390122c553e0Richard Smithtemplate<class T> auto h() -> A<T>;
776f3f69db1416425070177243e9f390122c553e0Richard Smithtemplate<class T> auto i(T) -> T;
876f3f69db1416425070177243e9f390122c553e0Richard Smithtemplate<class T> auto f(T) -> decltype(i(h<T>())); // #1
976f3f69db1416425070177243e9f390122c553e0Richard Smithtemplate<class T> auto f(T) -> void; // #2
1076f3f69db1416425070177243e9f390122c553e0Richard Smithauto g() -> void {
1176f3f69db1416425070177243e9f390122c553e0Richard Smith  f(42); // ok, calls #2, since #1 is not viable.
1276f3f69db1416425070177243e9f390122c553e0Richard Smith}
1376f3f69db1416425070177243e9f390122c553e0Richard Smithtemplate<class T> auto q(T) -> decltype((h<T>()));
1476f3f69db1416425070177243e9f390122c553e0Richard Smithvoid r() {
1576f3f69db1416425070177243e9f390122c553e0Richard Smith  // Deduction against q succeeds, but results in a temporary which can't be
1676f3f69db1416425070177243e9f390122c553e0Richard Smith  // destroyed.
1776f3f69db1416425070177243e9f390122c553e0Richard Smith  q(42); // expected-error {{attempt to use a deleted function}}
1876f3f69db1416425070177243e9f390122c553e0Richard Smith}
1976f3f69db1416425070177243e9f390122c553e0Richard Smith
2076f3f69db1416425070177243e9f390122c553e0Richard Smith}
2176f3f69db1416425070177243e9f390122c553e0Richard Smith
2276f3f69db1416425070177243e9f390122c553e0Richard Smithclass PD {
2376f3f69db1416425070177243e9f390122c553e0Richard Smith  friend struct A;
242f68ca09ca8b5944fcab14578a161511afde406fRichard Smith  ~PD(); // expected-note 5{{here}}
2576f3f69db1416425070177243e9f390122c553e0Richard Smithpublic:
2676f3f69db1416425070177243e9f390122c553e0Richard Smith  typedef int n;
2776f3f69db1416425070177243e9f390122c553e0Richard Smith};
2876f3f69db1416425070177243e9f390122c553e0Richard Smithstruct DD {
2976f3f69db1416425070177243e9f390122c553e0Richard Smith  ~DD() = delete; // expected-note 2{{here}}
3076f3f69db1416425070177243e9f390122c553e0Richard Smith  typedef int n;
3176f3f69db1416425070177243e9f390122c553e0Richard Smith};
3276f3f69db1416425070177243e9f390122c553e0Richard Smith
33651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesPD pd();
34651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesDD dd();
35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3676f3f69db1416425070177243e9f390122c553e0Richard Smithstruct A {
37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  decltype(pd()) s; // ok
38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  decltype(pd())::n n; // ok
39651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  decltype(dd()) *p = new decltype(dd()); // ok
4076f3f69db1416425070177243e9f390122c553e0Richard Smith};
41651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesA a();
4276f3f69db1416425070177243e9f390122c553e0Richard Smith
4376f3f69db1416425070177243e9f390122c553e0Richard Smith// Two errors here: one for the decltype, one for the variable.
442f68ca09ca8b5944fcab14578a161511afde406fRichard Smithdecltype(
45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    pd(), // expected-error {{private destructor}}
46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    pd()) pd1; // expected-error {{private destructor}}
47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesdecltype(dd(), // expected-error {{deleted function}}
48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines         dd()) dd1;
49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesdecltype(a(),
50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines         dd()) dd2; // expected-error {{deleted function}}
512f68ca09ca8b5944fcab14578a161511afde406fRichard Smithdecltype(
52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    pd(), // expected-error {{temporary of type 'PD' has private destructor}}
532f68ca09ca8b5944fcab14578a161511afde406fRichard Smith    0) pd2;
5476f3f69db1416425070177243e9f390122c553e0Richard Smith
55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesdecltype(((13, ((dd())))))::n dd_parens; // ok
56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesdecltype(((((42)), pd())))::n pd_parens_comma; // ok
5776f3f69db1416425070177243e9f390122c553e0Richard Smith
5876f3f69db1416425070177243e9f390122c553e0Richard Smith// Ensure parens aren't stripped from a decltype node.
59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesextern decltype(pd()) pd_ref; // ok
6076f3f69db1416425070177243e9f390122c553e0Richard Smithdecltype((pd_ref)) pd_ref3 = pd_ref; // ok, PD &
6176f3f69db1416425070177243e9f390122c553e0Richard Smithdecltype(pd_ref) pd_ref2 = pd_ref; // expected-error {{private destructor}}
6276f3f69db1416425070177243e9f390122c553e0Richard Smith
6376f3f69db1416425070177243e9f390122c553e0Richard Smithnamespace libcxx_example {
6476f3f69db1416425070177243e9f390122c553e0Richard Smith  struct nat {
6576f3f69db1416425070177243e9f390122c553e0Richard Smith    nat() = delete;
6676f3f69db1416425070177243e9f390122c553e0Richard Smith    nat(const nat&) = delete;
6776f3f69db1416425070177243e9f390122c553e0Richard Smith    nat &operator=(const nat&) = delete;
6876f3f69db1416425070177243e9f390122c553e0Richard Smith    ~nat() = delete;
6976f3f69db1416425070177243e9f390122c553e0Richard Smith  };
7076f3f69db1416425070177243e9f390122c553e0Richard Smith  struct any {
7176f3f69db1416425070177243e9f390122c553e0Richard Smith    any(...);
7276f3f69db1416425070177243e9f390122c553e0Richard Smith  };
7376f3f69db1416425070177243e9f390122c553e0Richard Smith
7476f3f69db1416425070177243e9f390122c553e0Richard Smith  template<typename T, typename U> struct is_same { static const bool value = false; };
7576f3f69db1416425070177243e9f390122c553e0Richard Smith  template<typename T> struct is_same<T, T> { static const bool value = true; };
7676f3f69db1416425070177243e9f390122c553e0Richard Smith
7776f3f69db1416425070177243e9f390122c553e0Richard Smith  template<typename T> T declval();
7876f3f69db1416425070177243e9f390122c553e0Richard Smith
7976f3f69db1416425070177243e9f390122c553e0Richard Smith  void swap(int &a, int &b);
8076f3f69db1416425070177243e9f390122c553e0Richard Smith  nat swap(any, any);
8176f3f69db1416425070177243e9f390122c553e0Richard Smith
8276f3f69db1416425070177243e9f390122c553e0Richard Smith  template<typename T> struct swappable {
8376f3f69db1416425070177243e9f390122c553e0Richard Smith    typedef decltype(swap(declval<T&>(), declval<T&>())) type;
8476f3f69db1416425070177243e9f390122c553e0Richard Smith    static const bool value = !is_same<type, nat>::value;
85840462670ba7a6bc26265a2306b35f2f0f01f51cRichard Smith    constexpr operator bool() const { return value; }
8676f3f69db1416425070177243e9f390122c553e0Richard Smith  };
8776f3f69db1416425070177243e9f390122c553e0Richard Smith
8876f3f69db1416425070177243e9f390122c553e0Richard Smith  static_assert(swappable<int>(), "");
8976f3f69db1416425070177243e9f390122c553e0Richard Smith  static_assert(!swappable<const int>(), "");
9076f3f69db1416425070177243e9f390122c553e0Richard Smith}
9176f3f69db1416425070177243e9f390122c553e0Richard Smith
9276f3f69db1416425070177243e9f390122c553e0Richard Smithnamespace RequireCompleteType {
9376f3f69db1416425070177243e9f390122c553e0Richard Smith  template<int N, bool OK> struct S {
9476f3f69db1416425070177243e9f390122c553e0Richard Smith    static_assert(OK, "boom!"); // expected-error 2{{boom!}}
9576f3f69db1416425070177243e9f390122c553e0Richard Smith  };
9676f3f69db1416425070177243e9f390122c553e0Richard Smith
9776f3f69db1416425070177243e9f390122c553e0Richard Smith  template<typename T> T make();
9876f3f69db1416425070177243e9f390122c553e0Richard Smith  template<int N, bool OK> S<N, OK> make();
9976f3f69db1416425070177243e9f390122c553e0Richard Smith  void consume(...);
10076f3f69db1416425070177243e9f390122c553e0Richard Smith
10176f3f69db1416425070177243e9f390122c553e0Richard Smith  decltype(make<0, false>()) *p1; // ok
10276f3f69db1416425070177243e9f390122c553e0Richard Smith  decltype((make<1, false>())) *p2; // ok
10376f3f69db1416425070177243e9f390122c553e0Richard Smith
10476f3f69db1416425070177243e9f390122c553e0Richard Smith  // A complete type is required here in order to detect an overloaded 'operator,'.
10576f3f69db1416425070177243e9f390122c553e0Richard Smith  decltype(123, make<2, false>()) *p3; // expected-note {{here}}
10676f3f69db1416425070177243e9f390122c553e0Richard Smith
10776f3f69db1416425070177243e9f390122c553e0Richard Smith  decltype(consume(make<3, false>())) *p4; // expected-note {{here}}
10876f3f69db1416425070177243e9f390122c553e0Richard Smith
10976f3f69db1416425070177243e9f390122c553e0Richard Smith  decltype(make<decltype(make<4, false>())>()) *p5; // ok
11076f3f69db1416425070177243e9f390122c553e0Richard Smith}
11176f3f69db1416425070177243e9f390122c553e0Richard Smith
11276f3f69db1416425070177243e9f390122c553e0Richard Smithnamespace Overload {
11376f3f69db1416425070177243e9f390122c553e0Richard Smith  DD operator+(PD &a, PD &b);
114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  decltype(pd()) *pd_ptr;
11576f3f69db1416425070177243e9f390122c553e0Richard Smith  decltype(*pd_ptr + *pd_ptr) *dd_ptr; // ok
11676f3f69db1416425070177243e9f390122c553e0Richard Smith
11776f3f69db1416425070177243e9f390122c553e0Richard Smith  decltype(0, *pd_ptr) pd_ref2 = pd_ref; // ok
11876f3f69db1416425070177243e9f390122c553e0Richard Smith  DD operator,(int a, PD b);
11976f3f69db1416425070177243e9f390122c553e0Richard Smith  decltype(0, *pd_ptr) *dd_ptr2; // expected-error {{private destructor}}
12076f3f69db1416425070177243e9f390122c553e0Richard Smith}
121