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