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: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