1 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++2a -ast-dump %s | FileCheck -strict-whitespace %s 2 3 template <typename, typename> 4 constexpr bool Concept = true; 5 template<typename T> // depth 0 6 struct Out { 7 template<typename U> // depth 1 8 struct Inner { 9 U t; 10 }; 11 12 template<typename V> // depth1 13 requires Concept<T, V> 14 Inner(V) -> Inner<V>; 15 }; 16 17 template <typename X> 18 struct Out2 { 19 template<typename Y> // depth1 20 using AInner = Out<int>::Inner<Y>; 21 }; 22 Out2<double>::AInner t(1.0); 23 24 // Verify that the require-clause of alias deduction guide is transformed correctly: 25 // - Occurrence T should be replaced with `int`; 26 // - Occurrence V should be replaced with the Y with depth 1 27 // - Depth of occurrence Y in the __is_deducible constraint should be 1 28 // 29 // CHECK: | `-FunctionTemplateDecl {{.*}} <deduction guide for AInner> 30 // CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} typename depth 0 index 0 Y 31 // CHECK-NEXT: | |-BinaryOperator {{.*}} '<dependent type>' '&&' 32 // CHECK-NEXT: | | |-UnresolvedLookupExpr {{.*}} '<dependent type>' lvalue (no ADL) = 'Concept' 33 // CHECK-NEXT: | | | |-TemplateArgument type 'int' 34 // CHECK-NEXT: | | | | `-BuiltinType {{.*}} 'int' 35 // CHECK-NEXT: | | | `-TemplateArgument type 'Y':'type-parameter-1-0' 36 // CHECK-NEXT: | | | `-TemplateTypeParmType {{.*}} 'Y' dependent depth 1 index 0 37 // CHECK-NEXT: | | | `-TemplateTypeParm {{.*}} 'Y' 38 // CHECK-NEXT: | | `-TypeTraitExpr {{.*}} 'bool' __is_deducible 39 // CHECK-NEXT: | | |-DeducedTemplateSpecializationType {{.*}} 'Out2<double>::AInner' dependent 40 // CHECK-NEXT: | | | `-name: 'Out2<double>::AInner' 41 // CHECK-NEXT: | | | `-TypeAliasTemplateDecl {{.+}} AInner{{$}} 42 // CHECK-NEXT: | | `-ElaboratedType {{.*}} 'Inner<Y>' sugar dependent 43 // CHECK-NEXT: | | `-TemplateSpecializationType {{.*}} 'Inner<Y>' dependent 44 // CHECK-NEXT: | | |-name: 'Inner':'Out<int>::Inner' qualified 45 // CHECK-NEXT: | | | `-ClassTemplateDecl {{.+}} Inner{{$}} 46 // CHECK-NEXT: | | `-TemplateArgument type 'Y' 47 // CHECK-NEXT: | | `-SubstTemplateTypeParmType {{.*}} 'Y' 48 // CHECK-NEXT: | | |-FunctionTemplate {{.*}} '<deduction guide for Inner>' 49 // CHECK-NEXT: | | `-TemplateTypeParmType {{.*}} 'Y' dependent depth 1 index 0 50 // CHECK-NEXT: | | `-TemplateTypeParm {{.*}} 'Y' 51 // CHECK-NEXT: | |-CXXDeductionGuideDecl {{.*}} <deduction guide for AInner> 'auto (Y) -> Inner<Y>' 52 // CHECK-NEXT: | | `-ParmVarDecl {{.*}} 'Y' 53 // CHECK-NEXT: | `-CXXDeductionGuideDecl {{.*}} used <deduction guide for AInner> 'auto (double) -> Inner<double>' implicit_instantiation 54 // CHECK-NEXT: | |-TemplateArgument type 'double' 55 // CHECK-NEXT: | | `-BuiltinType {{.*}} 'double' 56 // CHECK-NEXT: | `-ParmVarDecl {{.*}} 'double' 57 58 // GH92596 59 template <typename T0> 60 struct Out3 { 61 template<class T1, typename T2> 62 struct Foo { 63 // Deduction guide: 64 // template <typename T1, typename T2, typename V> 65 // Foo(V, T1) -> Foo<T1, T2>; 66 template<class V> requires Concept<T0, V> // V in require clause of Foo deduction guide: depth 1, index: 2 67 Foo(V, T1); 68 }; 69 }; 70 template<class T3> 71 using AFoo3 = Out3<int>::Foo<T3, T3>; 72 AFoo3 afoo3{0, 1}; 73 // Verify occurrence V in the require-clause is transformed (depth: 1 => 0, index: 2 => 1) correctly. 74 75 // CHECK: FunctionTemplateDecl {{.*}} implicit <deduction guide for AFoo3> 76 // CHECK-NEXT: |-TemplateTypeParmDecl {{.*}} class depth 0 index 0 T3 77 // CHECK-NEXT: |-TemplateTypeParmDecl {{.*}} class depth 0 index 1 V 78 // CHECK-NEXT: |-BinaryOperator {{.*}} '<dependent type>' '&&' 79 // CHECK-NEXT: | |-UnresolvedLookupExpr {{.*}} '<dependent type>' lvalue (no ADL) = 'Concept' 80 // CHECK-NEXT: | | |-TemplateArgument type 'int' 81 // CHECK-NEXT: | | | `-BuiltinType {{.*}} 'int' 82 // CHECK-NEXT: | | `-TemplateArgument type 'V' 83 // CHECK-NEXT: | | `-TemplateTypeParmType {{.*}} 'V' dependent depth 0 index 1 84 85 template <typename... T1> 86 struct Foo { 87 Foo(T1...); 88 }; 89 90 template <typename...T2> 91 using AFoo = Foo<T2...>; 92 AFoo a(1, 2); 93 // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for AFoo> 'auto (T2...) -> Foo<T2...>' 94 // CHECK-NEXT: | | `-ParmVarDecl {{.*}} 'T2...' pack 95 // CHECK-NEXT: | `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for AFoo> 'auto (int, int) -> Foo<int, int>' implicit_instantiation 96 97 template <typename T> 98 using BFoo = Foo<T, T>; 99 BFoo b2(1.0, 2.0); 100 // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for BFoo> 'auto (T, T) -> Foo<T, T>' 101 // CHECK-NEXT: | | |-ParmVarDecl {{.*}} 'T' 102 // CHECK-NEXT: | | `-ParmVarDecl {{.*}} 'T' 103 // CHECK-NEXT: | `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for BFoo> 'auto (double, double) -> Foo<double, double>' implicit_instantiation 104 105 namespace GH90209 { 106 // Case 1: type template parameter 107 template <class Ts> 108 struct List1 { 109 List1(int); 110 }; 111 112 template <class T1> 113 struct TemplatedClass1 { 114 TemplatedClass1(T1); 115 }; 116 117 template <class T1> 118 TemplatedClass1(T1) -> TemplatedClass1<List1<T1>>; 119 120 template <class T2> 121 using ATemplatedClass1 = TemplatedClass1<List1<T2>>; 122 123 ATemplatedClass1 test1(1); 124 // Verify that we have a correct template parameter list for the deduction guide. 125 // 126 // CHECK: FunctionTemplateDecl {{.*}} <deduction guide for ATemplatedClass1> 127 // CHECK-NEXT: |-TemplateTypeParmDecl {{.*}} class depth 0 index 0 T2 128 // CHECK-NEXT: |-TypeTraitExpr {{.*}} 'bool' __is_deducible 129 130 // Case 2: template template parameter 131 template<typename K> struct Foo{}; 132 133 template <template<typename> typename Ts> 134 struct List2 { 135 List2(int); 136 }; 137 138 template <typename T1> 139 struct TemplatedClass2 { 140 TemplatedClass2(T1); 141 }; 142 143 template <template<typename> typename T1> 144 TemplatedClass2(T1<int>) -> TemplatedClass2<List2<T1>>; 145 146 template <template<typename> typename T2> 147 using ATemplatedClass2 = TemplatedClass2<List2<T2>>; 148 149 List2<Foo> list(1); 150 ATemplatedClass2 test2(list); 151 // Verify that we have a correct template parameter list for the deduction guide. 152 // 153 // CHECK: FunctionTemplateDecl {{.*}} <deduction guide for ATemplatedClass2> 154 // CHECK-NEXT: |-TemplateTemplateParmDecl {{.*}} depth 0 index 0 T2 155 // CHECK-NEXT: | `-TemplateTypeParmDecl {{.*}} typename depth 0 index 0 156 // CHECK-NEXT: |-TypeTraitExpr {{.*}} 'bool' __is_deducible 157 158 } // namespace GH90209 159