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