Home | History | Annotate | Download | only in dcl.type.simple
      1 // RUN: %clang_cc1 -std=c++11 -verify %s
      2 
      3 namespace std_example {
      4 
      5 template<class T> struct A { ~A() = delete; }; // expected-note {{deleted here}}
      6 template<class T> auto h() -> A<T>;
      7 template<class T> auto i(T) -> T;
      8 template<class T> auto f(T) -> decltype(i(h<T>())); // #1
      9 template<class T> auto f(T) -> void; // #2
     10 auto g() -> void {
     11   f(42); // ok, calls #2, since #1 is not viable.
     12 }
     13 template<class T> auto q(T) -> decltype((h<T>()));
     14 void r() {
     15   // Deduction against q succeeds, but results in a temporary which can't be
     16   // destroyed.
     17   q(42); // expected-error {{attempt to use a deleted function}}
     18 }
     19 
     20 }
     21 
     22 class PD {
     23   friend struct A;
     24   ~PD(); // expected-note 5{{here}}
     25 public:
     26   typedef int n;
     27 };
     28 struct DD {
     29   ~DD() = delete; // expected-note 2{{here}}
     30   typedef int n;
     31 };
     32 
     33 struct A {
     34   decltype(PD()) s; // ok
     35   decltype(PD())::n n; // ok
     36   decltype(DD()) *p = new decltype(DD()); // ok
     37 };
     38 
     39 // Two errors here: one for the decltype, one for the variable.
     40 decltype(
     41     PD(), // expected-error {{private destructor}}
     42     PD()) pd1; // expected-error {{private destructor}}
     43 decltype(DD(), // expected-error {{deleted function}}
     44          DD()) dd1; // expected-error {{deleted function}}
     45 decltype(
     46     PD(), // expected-error {{temporary of type 'PD' has private destructor}}
     47     0) pd2;
     48 
     49 decltype(((13, ((DD())))))::n dd_parens; // ok
     50 decltype(((((42)), PD())))::n pd_parens_comma; // ok
     51 
     52 // Ensure parens aren't stripped from a decltype node.
     53 extern decltype(PD()) pd_ref; // ok
     54 decltype((pd_ref)) pd_ref3 = pd_ref; // ok, PD &
     55 decltype(pd_ref) pd_ref2 = pd_ref; // expected-error {{private destructor}}
     56 
     57 namespace libcxx_example {
     58   struct nat {
     59     nat() = delete;
     60     nat(const nat&) = delete;
     61     nat &operator=(const nat&) = delete;
     62     ~nat() = delete;
     63   };
     64   struct any {
     65     any(...);
     66   };
     67 
     68   template<typename T, typename U> struct is_same { static const bool value = false; };
     69   template<typename T> struct is_same<T, T> { static const bool value = true; };
     70 
     71   template<typename T> T declval();
     72 
     73   void swap(int &a, int &b);
     74   nat swap(any, any);
     75 
     76   template<typename T> struct swappable {
     77     typedef decltype(swap(declval<T&>(), declval<T&>())) type;
     78     static const bool value = !is_same<type, nat>::value;
     79     constexpr operator bool() { return value; }
     80   };
     81 
     82   static_assert(swappable<int>(), "");
     83   static_assert(!swappable<const int>(), "");
     84 }
     85 
     86 namespace RequireCompleteType {
     87   template<int N, bool OK> struct S {
     88     static_assert(OK, "boom!"); // expected-error 2{{boom!}}
     89   };
     90 
     91   template<typename T> T make();
     92   template<int N, bool OK> S<N, OK> make();
     93   void consume(...);
     94 
     95   decltype(make<0, false>()) *p1; // ok
     96   decltype((make<1, false>())) *p2; // ok
     97 
     98   // A complete type is required here in order to detect an overloaded 'operator,'.
     99   decltype(123, make<2, false>()) *p3; // expected-note {{here}}
    100 
    101   decltype(consume(make<3, false>())) *p4; // expected-note {{here}}
    102 
    103   decltype(make<decltype(make<4, false>())>()) *p5; // ok
    104 }
    105 
    106 namespace Overload {
    107   DD operator+(PD &a, PD &b);
    108   decltype(PD()) *pd_ptr;
    109   decltype(*pd_ptr + *pd_ptr) *dd_ptr; // ok
    110 
    111   decltype(0, *pd_ptr) pd_ref2 = pd_ref; // ok
    112   DD operator,(int a, PD b);
    113   decltype(0, *pd_ptr) *dd_ptr2; // expected-error {{private destructor}}
    114 }
    115