1 // Test without serialization:
2 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -ast-dump %s \
3 // RUN: | FileCheck -strict-whitespace %s
4 //
5 // Test with serialization:
6 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -emit-pch -o %t %s
7 // RUN: %clang_cc1 -x c++ -std=c++17 -triple x86_64-unknown-unknown -include-pch %t -ast-dump-all /dev/null \
8 // RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \
9 // RUN: | FileCheck --strict-whitespace %s
10 
11 template <typename Ty>
12 // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <{{.*}}:1, line:[[@LINE+2]]:10> col:6 a
13 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 referenced typename depth 0 index 0 Ty
14 void a(Ty);
15 
16 template <typename... Ty>
17 // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:13> col:6 b
18 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:23> col:23 referenced typename depth 0 index 0 ... Ty
19 void b(Ty...);
20 
21 template <typename Ty, typename Uy>
22 // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:14> col:6 c
23 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 referenced typename depth 0 index 0 Ty
24 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <col:24, col:33> col:33 referenced typename depth 0 index 1 Uy
25 void c(Ty, Uy);
26 
27 template <>
28 void c<float, int>(float, int);
29 // CHECK: FunctionDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} <line:[[@LINE-2]]:1, line:[[@LINE-1]]:30> col:6 c 'void (float, int)'
30 // CHECK: TemplateArgument type 'float'
31 // CHECK: TemplateArgument type 'int'
32 
33 template <typename Ty, template<typename> typename Uy>
34 // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+4]]:18> col:6 d
35 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 referenced typename depth 0 index 0 Ty
36 // CHECK-NEXT: TemplateTemplateParmDecl 0x{{[^ ]*}} <col:24, col:52> col:52 depth 0 index 1 Uy
37 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <col:33> col:41 typename depth 1 index 0
38 void d(Ty, Uy<Ty>);
39 
40 template <class Ty>
41 // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:10> col:6 e
42 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:17> col:17 referenced class depth 0 index 0 Ty
43 void e(Ty);
44 
45 template <int N>
46 // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:17> col:6 f
47 // CHECK-NEXT: NonTypeTemplateParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:15> col:15 referenced 'int' depth 0 index 0 N
48 void f(int i = N);
49 
50 template <typename Ty = int>
51 // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:10> col:6 g
52 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:25> col:20 referenced typename depth 0 index 0 Ty
53 // CHECK-NEXT: TemplateArgument type 'int'
54 void g(Ty);
55 
56 template <typename = void>
57 // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:8> col:6 h
58 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:22> col:20 typename depth 0 index 0
59 // CHECK-NEXT: TemplateArgument type 'void'
60 void h();
61 
62 template <typename Ty>
63 // CHECK: ClassTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:11> col:8 R
64 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 typename depth 0 index 0 Ty
65 // CHECK: ClassTemplateSpecialization 0x{{[^ ]*}} 'R'
66 struct R {};
67 
68 template <>
69 // CHECK: ClassTemplateSpecializationDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:16> col:8 struct R definition
70 // CHECK: TemplateArgument type 'int'
71 struct R<int> {};
72 
73 template <typename Ty, class Uy>
74 // CHECK: ClassTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:11> col:8 S
75 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 typename depth 0 index 0 Ty
76 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <col:24, col:30> col:30 class depth 0 index 1 Uy
77 struct S {};
78 
79 template <typename Ty>
80 // CHECK: ClassTemplatePartialSpecializationDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+4]]:20> col:8 struct S definition
81 // CHECK: TemplateArgument type 'type-parameter-0-0'
82 // CHECK: TemplateArgument type 'int'
83 // CHECK: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-4]]:11, col:20> col:20 referenced typename depth 0 index 0 Ty
84 struct S<Ty, int> {};
85 
86 template <auto>
87 // CHECK: ClassTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:11> col:8 T
88 // CHECK-NEXT: NonTypeTemplateParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11> col:15 'auto' depth 0 index 0
89 struct T {};
90 
91 template <decltype(auto)>
92 // CHECK: ClassTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:11> col:8 U
93 // CHECK-NEXT: NonTypeTemplateParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:24> col:25 'decltype(auto)' depth 0 index 0
94 struct U {};
95 
96 template <typename Ty>
97 // CHECK: ClassTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+7]]:1> line:[[@LINE+2]]:8 V
98 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 typename depth 0 index 0 Ty
99 struct V {
100   template <typename Uy>
101   // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+2]]:10> col:8 f
102   // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:13, col:22> col:22 typename depth 1 index 0 Uy
103   void f();
104 };
105 
106 template <typename Ty>
107 template <typename Uy>
108 // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} parent 0x{{[^ ]*}} prev 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:18> col:13 f
109 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 typename depth 1 index 0 Uy
f()110 void V<Ty>::f() {}
111 
112 namespace PR55886 {
113 template <class T> struct C {
114   template <class U> using type1 = U(T);
115 };
116 using type2 = typename C<int>::type1<void>;
117 // CHECK:      TypeAliasDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:42> col:7 type2 'typename C<int>::type1<void>':'void (int)'
118 // CHECK-NEXT: ElaboratedType 0x{{[^ ]*}} 'typename C<int>::type1<void>' sugar
119 // CHECK-NEXT: TemplateSpecializationType 0x{{[^ ]*}} 'type1<void>' sugar alias type1
120 // CHECK-NEXT: TemplateArgument type 'void'
121 // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'void'
122 // CHECK-NEXT: FunctionProtoType 0x{{[^ ]*}} 'void (int)' cdecl
123 // CHECK-NEXT: SubstTemplateTypeParmType 0x{{[^ ]*}} 'void' sugar
124 // CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'U' dependent depth 0 index 0
125 // CHECK-NEXT: TemplateTypeParm 0x{{[^ ]*}} 'U'
126 // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'void'
127 // CHECK-NEXT: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar
128 // CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'T' dependent depth 0 index 0
129 } // namespace PR55886
130 
131 namespace PR56099 {
132 template <typename... As> struct Y;
133 template <typename... Bs> using Z = Y<Bs...>;
134 template <typename... Cs> struct foo {
135   template <typename... Ds> using bind = Z<Ds..., Cs...>;
136 };
137 using t1 = foo<int, short>::bind<char, float>;
138 // CHECK:      TemplateSpecializationType 0x{{[^ ]*}} 'Y<char, float, int, short>' sugar Y
139 // CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar
140 // CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack
141 // CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar
142 // CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack
143 // CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar
144 // CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack
145 // CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar
146 // CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack
147 
148 template <typename... T> struct D {
149   template <typename... U> using B = int(int (*...p)(T, U));
150 };
151 using t2 = D<float, char>::B<int, short>;
152 // CHECK:      TemplateSpecializationType 0x{{[^ ]*}} 'B<int, short>' sugar alias B
153 // CHECK:      FunctionProtoType 0x{{[^ ]*}} 'int (int (*)(float, int), int (*)(char, short))' cdecl
154 // CHECK:      FunctionProtoType 0x{{[^ ]*}} 'int (float, int)' cdecl
155 // CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar
156 // CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'T' dependent contains_unexpanded_pack depth 0 index 0 pack
157 // CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar
158 // CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'U' dependent contains_unexpanded_pack depth 0 index 0 pack
159 // CHECK:      FunctionProtoType 0x{{[^ ]*}} 'int (char, short)' cdecl
160 // CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar
161 // CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'T' dependent contains_unexpanded_pack depth 0 index 0 pack
162 // CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar
163 // CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'U' dependent contains_unexpanded_pack depth 0 index 0 pack
164 } // namespace PR56099
165