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