1 // RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t-cxx2a
2 // RUN: %clang_cc1 -std=c++2a -DUSE_PCH -include-pch %t-cxx2a %s -ast-print -verify | FileCheck %s
3 
4 #ifndef USE_PCH
5 namespace inheriting_constructor {
6   struct S {};
7 
8   template<typename X, typename Y> struct T {
9     template<typename A>
10     explicit((Y{}, true)) T(A &&a) {}
11   };
12 
13   template<typename X, typename Y> struct U : T<X, Y> {
14     using T<X, Y>::T;
15   };
16 
17   U<S, char> foo(char ch) {
18     return U<S, char>(ch);
19   }
20 }
21 #else
22 namespace inheriting_constructor {
23 U<S, char> a = foo('0');
24 }
25 
26 //CHECK: explicit((char{} , true))
27 
28 #endif
29 
30 namespace basic {
31 #ifndef USE_PCH
32 
33 struct B {};
34 
35 struct A {
36   explicit A(int);
37   explicit(false) operator bool();
38   explicit(true) operator B();
39 };
40 #else
41 //expected-note@-6+ {{candidate constructor}}
42 //expected-note@-9+ {{candidate constructor}}
43 //expected-note-re@-7+ {{explicit constructor is not a candidate{{$}}}}
44 //expected-note@-7+ {{candidate function}}
45 //expected-note@-7+ {{explicit conversion function is not a candidate (explicit specifier evaluates to true)}}
46 
47 //CHECK: explicit{{ +}}A(
48 //CHECK-NEXT: explicit(false){{ +}}operator
49 //CHECK-NEXT: explicit(true){{ +}}operator
50 A a = 0; //expected-error {{no viable conversion}}
51 A a1(0);
52 
53 bool b = a1;
54 B b1 = a1; //expected-error {{no viable conversion}}
55 
56 #endif
57 }
58 
59 
60 namespace templ {
61 #ifndef USE_PCH
62 
63 template<bool b>
64 struct B {
65   static constexpr bool value = b;
66 };
67 
68 template<bool b>
69 struct A {
70   explicit(b) A(B<b>) {}
71   template<typename T>
72   explicit(b ^ T::value) operator T();
73 };
74 B<true> b_true;
75 B<false> b_false;
76 #else
77 //expected-note@-8 {{candidate template ignored}}
78 //expected-note@-8 {{explicit constructor declared here}}
79 //expected-note@-15+ {{candidate constructor}}
80 //expected-note@-8+ {{explicit conversion function is not a candidate (explicit specifier}}
81 //expected-note@-11 {{explicit constructor is not a candidate (explicit specifier}}
82 
83 //CHECK: explicit(b){{ +}}A
84 //CHECK: explicit(b{{ +}}^{{ +}}T::value){{ +}}operator
85 
86 A a = { b_true }; //expected-error {{class template argument deduction}}
87 A a0 = b_true; //expected-error {{no viable constructor or deduction guide}}
88 A a_true(b_true);
89 A a_false = b_false;
90 
91 B<true> b = a_true;
92 B<true> b1 = a_false; //expected-error {{no viable conversion}}
93 B<false> b2(a_true);
94 
95 #endif
96 
97 }
98 
99 namespace guide {
100 
101 #ifndef USE_PCH
102 
103 template<typename T>
104 struct A {
105   A(T);
106 };
107 
108 template<typename T>
109 explicit(true) A(T) -> A<T>;
110 
111 explicit(false) A(int) -> A<int>;
112 
113 #else
114 //expected-note@-5 {{explicit deduction guide}}
115 
116 //CHECK: explicit(true){{ +}}A(
117 //CHECK: explicit(false){{ +}}A(
118 
119 A a = { 0.0 }; //expected-error {{explicit deduction guide}}
120 A a1 = { 0 };
121 
122 #endif
123 
124 }
125