File: ast-dump-sycl-kernel-entry-point.cpp

package info (click to toggle)
llvm-toolchain-20 1%3A20.1.8-1~exp1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 2,111,388 kB
  • sloc: cpp: 7,438,767; ansic: 1,393,871; asm: 1,012,926; python: 241,728; f90: 86,635; objc: 75,411; lisp: 42,144; pascal: 17,286; sh: 10,027; ml: 5,082; perl: 4,730; awk: 3,523; makefile: 3,349; javascript: 2,251; xml: 892; fortran: 672
file content (157 lines) | stat: -rw-r--r-- 6,681 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Tests without serialization:
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-device \
// RUN:   -ast-dump %s \
// RUN:   | FileCheck --match-full-lines %s
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-host \
// RUN:   -ast-dump %s \
// RUN:   | FileCheck --match-full-lines %s
//
// Tests with serialization:
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-device \
// RUN:   -emit-pch -o %t %s
// RUN: %clang_cc1 -x c++ -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-device \
// RUN:   -include-pch %t -ast-dump-all /dev/null \
// RUN:   | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \
// RUN:   | FileCheck --match-full-lines %s
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-host \
// RUN:   -emit-pch -o %t %s
// RUN: %clang_cc1 -x c++ -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-host \
// RUN:   -include-pch %t -ast-dump-all /dev/null \
// RUN:   | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \
// RUN:   | FileCheck --match-full-lines %s

// These tests validate the AST produced for functions declared with the
// sycl_kernel_entry_point attribute.

// CHECK: TranslationUnitDecl {{.*}}

// A unique kernel name type is required for each declared kernel entry point.
template<int, int=0> struct KN;

__attribute__((sycl_kernel_entry_point(KN<1>)))
void skep1() {
}
// CHECK:      |-FunctionDecl {{.*}} skep1 'void ()'
// CHECK:      | `-SYCLKernelEntryPointAttr {{.*}} KN<1>

using KN2 = KN<2>;
__attribute__((sycl_kernel_entry_point(KN2)))
void skep2() {
}
// CHECK:      |-FunctionDecl {{.*}} skep2 'void ()'
// CHECK:      | `-SYCLKernelEntryPointAttr {{.*}} KN2

template<int I> using KNT = KN<I>;
__attribute__((sycl_kernel_entry_point(KNT<3>)))
void skep3() {
}
// CHECK:      |-FunctionDecl {{.*}} skep3 'void ()'
// CHECK:      | `-SYCLKernelEntryPointAttr {{.*}} KNT<3>

template<typename KNT, typename F>
[[clang::sycl_kernel_entry_point(KNT)]]
void skep4(F f) {
  f();
}
// CHECK:      |-FunctionTemplateDecl {{.*}} skep4
// CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} KNT
// CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} F
// CHECK-NEXT: | |-FunctionDecl {{.*}} skep4 'void (F)'
// CHECK:      | | `-SYCLKernelEntryPointAttr {{.*}} KNT

void test_skep4() {
  skep4<KNT<4>>([]{});
}
// CHECK:      | `-FunctionDecl {{.*}} used skep4 'void ((lambda at {{.*}}))' implicit_instantiation
// CHECK-NEXT: |   |-TemplateArgument type 'KN<4>'
// CHECK:      |   |-TemplateArgument type '(lambda at {{.*}})'
// CHECK:      |   `-SYCLKernelEntryPointAttr {{.*}} struct KN<4>
// CHECK-NEXT: |-FunctionDecl {{.*}} test_skep4 'void ()'

template<typename KNT, typename T>
[[clang::sycl_kernel_entry_point(KNT)]]
void skep5(T) {
}
// CHECK:      |-FunctionTemplateDecl {{.*}} skep5
// CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} KNT
// CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} T
// CHECK-NEXT: | |-FunctionDecl {{.*}} skep5 'void (T)'
// CHECK:      | | `-SYCLKernelEntryPointAttr {{.*}} KNT

// Checks for the explicit template instantiation declaration below.
// CHECK:      | `-FunctionDecl {{.*}} skep5 'void (int)' explicit_instantiation_definition
// CHECK-NEXT: |   |-TemplateArgument type 'KN<5, 4>'
// CHECK:      |   |-TemplateArgument type 'int'
// CHECK:      |   `-SYCLKernelEntryPointAttr {{.*}} KN<5, 4>

// FIXME: C++23 [temp.expl.spec]p12 states:
// FIXME:   ... Similarly, attributes appearing in the declaration of a template
// FIXME:   have no effect on an explicit specialization of that template.
// FIXME: Clang currently instantiates and propagates attributes from a function
// FIXME: template to its explicit specializations resulting in the following
// FIXME: explicit specialization having an attribute incorrectly attached.
template<>
void skep5<KN<5,1>>(short) {
}
// CHECK:      |-FunctionDecl {{.*}} prev {{.*}} skep5 'void (short)' explicit_specialization
// CHECK-NEXT: | |-TemplateArgument type 'KN<5, 1>'
// CHECK:      | |-TemplateArgument type 'short'
// CHECK:      | `-SYCLKernelEntryPointAttr {{.*}} Inherited struct KN<5, 1>

template<>
[[clang::sycl_kernel_entry_point(KN<5,2>)]]
void skep5<KN<5,2>>(long) {
}
// CHECK:      |-FunctionDecl {{.*}} prev {{.*}} skep5 'void (long)' explicit_specialization
// CHECK-NEXT: | |-TemplateArgument type 'KN<5, 2>'
// CHECK:      | |-TemplateArgument type 'long'
// CHECK:      | `-SYCLKernelEntryPointAttr {{.*}} KN<5, 2>

// FIXME: C++23 [temp.expl.spec]p12 states:
// FIXME:   ... Similarly, attributes appearing in the declaration of a template
// FIXME:   have no effect on an explicit specialization of that template.
// FIXME: Clang currently instantiates a function template specialization from
// FIXME: the function template declaration and links it as a previous
// FIXME: declaration of an explicit specialization. The instantiated
// FIXME: declaration includes attributes instantiated from the function
// FIXME: template declaration. When the instantiated declaration and the
// FIXME: explicit specialization both specify a sycl_kernel_entry_point
// FIXME: attribute with different kernel name types, a spurious diagnostic
// FIXME: is issued. The following test case is incorrectly diagnosed as
// FIXME: having conflicting kernel name types (KN<5,3> vs the incorrectly
// FIXME: inherited KN<5,-1>).
#if 0
template<>
[[clang::sycl_kernel_entry_point(KN<5,3>)]]
void skep5<KN<5,-1>>(long long) {
}
// FIXME-CHECK:      |-FunctionDecl {{.*}} prev {{.*}} skep5 'void (long long)' explicit_specialization
// FIXME-CHECK-NEXT: | |-TemplateArgument type 'KN<5, -1>'
// FIXME-CHECK:      | |-TemplateArgument type 'long long'
// FIXME-CHECK:      | `-SYCLKernelEntryPointAttr {{.*}} KN<5, 3>
#endif

template void skep5<KN<5,4>>(int);
// Checks are located with the primary template declaration above.

// Ensure that matching attributes from multiple declarations are ok.
[[clang::sycl_kernel_entry_point(KN<6>)]]
void skep6();
[[clang::sycl_kernel_entry_point(KN<6>)]]
void skep6() {
}
// CHECK:      |-FunctionDecl {{.*}} skep6 'void ()'
// CHECK-NEXT: | `-SYCLKernelEntryPointAttr {{.*}} KN<6>
// CHECK-NEXT: |-FunctionDecl {{.*}} prev {{.*}} skep6 'void ()'
// CHECK:      | `-SYCLKernelEntryPointAttr {{.*}} KN<6>

// Ensure that matching attributes from the same declaration are ok.
[[clang::sycl_kernel_entry_point(KN<7>), clang::sycl_kernel_entry_point(KN<7>)]]
void skep7() {
}
// CHECK:      |-FunctionDecl {{.*}} skep7 'void ()'
// CHECK:      | |-SYCLKernelEntryPointAttr {{.*}} KN<7>
// CHECK-NEXT: | `-SYCLKernelEntryPointAttr {{.*}} KN<7>

void the_end() {}
// CHECK:      `-FunctionDecl {{.*}} the_end 'void ()'