158 lines · cpp
1// Tests without serialization:2// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-device \3// RUN: -ast-dump %s \4// RUN: | FileCheck --match-full-lines %s5// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-host \6// RUN: -ast-dump %s \7// RUN: | FileCheck --match-full-lines %s8//9// Tests with serialization:10// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-device \11// RUN: -emit-pch -o %t %s12// RUN: %clang_cc1 -x c++ -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-device \13// RUN: -include-pch %t -ast-dump-all /dev/null \14// RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \15// RUN: | FileCheck --match-full-lines %s16// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-host \17// RUN: -emit-pch -o %t %s18// RUN: %clang_cc1 -x c++ -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-host \19// RUN: -include-pch %t -ast-dump-all /dev/null \20// RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \21// RUN: | FileCheck --match-full-lines %s22 23// These tests validate the AST produced for functions declared with the24// sycl_kernel_entry_point attribute.25 26// CHECK: TranslationUnitDecl {{.*}}27 28// A unique kernel name type is required for each declared kernel entry point.29template<int, int=0> struct KN;30 31[[clang::sycl_kernel_entry_point(KN<1>)]]32void skep1() {33}34// CHECK: |-FunctionDecl {{.*}} skep1 'void ()'35// CHECK: | `-SYCLKernelEntryPointAttr {{.*}} KN<1>36 37using KN2 = KN<2>;38[[clang::sycl_kernel_entry_point(KN2)]]39void skep2() {40}41// CHECK: |-FunctionDecl {{.*}} skep2 'void ()'42// CHECK: | `-SYCLKernelEntryPointAttr {{.*}} KN243 44template<int I> using KNT = KN<I>;45[[clang::sycl_kernel_entry_point(KNT<3>)]]46void skep3() {47}48// CHECK: |-FunctionDecl {{.*}} skep3 'void ()'49// CHECK: | `-SYCLKernelEntryPointAttr {{.*}} KNT<3>50 51template<typename KNT, typename F>52[[clang::sycl_kernel_entry_point(KNT)]]53void skep4(F f) {54 f();55}56// CHECK: |-FunctionTemplateDecl {{.*}} skep457// CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} KNT58// CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} F59// CHECK-NEXT: | |-FunctionDecl {{.*}} skep4 'void (F)'60// CHECK: | | `-SYCLKernelEntryPointAttr {{.*}} KNT61 62void test_skep4() {63 skep4<KNT<4>>([]{});64}65// CHECK: | `-FunctionDecl {{.*}} used skep4 'void ((lambda at {{.*}}))' implicit_instantiation instantiated_from 0x{{.+}}66// CHECK-NEXT: | |-TemplateArgument type 'KN<4>'67// CHECK: | |-TemplateArgument type '(lambda at {{.*}})'68// CHECK: | `-SYCLKernelEntryPointAttr {{.*}} struct KN<4>69// CHECK-NEXT: |-FunctionDecl {{.*}} test_skep4 'void ()'70 71template<typename KNT, typename T>72[[clang::sycl_kernel_entry_point(KNT)]]73void skep5(T) {74}75// CHECK: |-FunctionTemplateDecl {{.*}} skep576// CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} KNT77// CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} T78// CHECK-NEXT: | |-FunctionDecl {{.*}} skep5 'void (T)'79// CHECK: | | `-SYCLKernelEntryPointAttr {{.*}} KNT80 81// Checks for the explicit template instantiation declaration below.82// CHECK: | `-FunctionDecl {{.*}} skep5 'void (int)' explicit_instantiation_definition instantiated_from 0x{{.+}}83// CHECK-NEXT: | |-TemplateArgument type 'KN<5, 4>'84// CHECK: | |-TemplateArgument type 'int'85// CHECK: | `-SYCLKernelEntryPointAttr {{.*}} KN<5, 4>86 87// FIXME: C++23 [temp.expl.spec]p12 states:88// FIXME: ... Similarly, attributes appearing in the declaration of a template89// FIXME: have no effect on an explicit specialization of that template.90// FIXME: Clang currently instantiates and propagates attributes from a function91// FIXME: template to its explicit specializations resulting in the following92// FIXME: explicit specialization having an attribute incorrectly attached.93template<>94void skep5<KN<5,1>>(short) {95}96// CHECK: |-FunctionDecl {{.*}} prev {{.*}} skep5 'void (short)' explicit_specialization97// CHECK-NEXT: | |-TemplateArgument type 'KN<5, 1>'98// CHECK: | |-TemplateArgument type 'short'99// CHECK: | `-SYCLKernelEntryPointAttr {{.*}} Inherited struct KN<5, 1>100 101template<>102[[clang::sycl_kernel_entry_point(KN<5,2>)]]103void skep5<KN<5,2>>(long) {104}105// CHECK: |-FunctionDecl {{.*}} prev {{.*}} skep5 'void (long)' explicit_specialization106// CHECK-NEXT: | |-TemplateArgument type 'KN<5, 2>'107// CHECK: | |-TemplateArgument type 'long'108// CHECK: | `-SYCLKernelEntryPointAttr {{.*}} KN<5, 2>109 110// FIXME: C++23 [temp.expl.spec]p12 states:111// FIXME: ... Similarly, attributes appearing in the declaration of a template112// FIXME: have no effect on an explicit specialization of that template.113// FIXME: Clang currently instantiates a function template specialization from114// FIXME: the function template declaration and links it as a previous115// FIXME: declaration of an explicit specialization. The instantiated116// FIXME: declaration includes attributes instantiated from the function117// FIXME: template declaration. When the instantiated declaration and the118// FIXME: explicit specialization both specify a sycl_kernel_entry_point119// FIXME: attribute with different kernel name types, a spurious diagnostic120// FIXME: is issued. The following test case is incorrectly diagnosed as121// FIXME: having conflicting kernel name types (KN<5,3> vs the incorrectly122// FIXME: inherited KN<5,-1>).123#if 0124template<>125[[clang::sycl_kernel_entry_point(KN<5,3>)]]126void skep5<KN<5,-1>>(long long) {127}128// FIXME-CHECK: |-FunctionDecl {{.*}} prev {{.*}} skep5 'void (long long)' explicit_specialization129// FIXME-CHECK-NEXT: | |-TemplateArgument type 'KN<5, -1>'130// FIXME-CHECK: | |-TemplateArgument type 'long long'131// FIXME-CHECK: | `-SYCLKernelEntryPointAttr {{.*}} KN<5, 3>132#endif133 134template void skep5<KN<5,4>>(int);135// Checks are located with the primary template declaration above.136 137// Ensure that matching attributes from multiple declarations are ok.138[[clang::sycl_kernel_entry_point(KN<6>)]]139void skep6();140[[clang::sycl_kernel_entry_point(KN<6>)]]141void skep6() {142}143// CHECK: |-FunctionDecl {{.*}} skep6 'void ()'144// CHECK-NEXT: | `-SYCLKernelEntryPointAttr {{.*}} KN<6>145// CHECK-NEXT: |-FunctionDecl {{.*}} prev {{.*}} skep6 'void ()'146// CHECK: | `-SYCLKernelEntryPointAttr {{.*}} KN<6>147 148// Ensure that matching attributes from the same declaration are ok.149[[clang::sycl_kernel_entry_point(KN<7>), clang::sycl_kernel_entry_point(KN<7>)]]150void skep7() {151}152// CHECK: |-FunctionDecl {{.*}} skep7 'void ()'153// CHECK: | |-SYCLKernelEntryPointAttr {{.*}} KN<7>154// CHECK-NEXT: | `-SYCLKernelEntryPointAttr {{.*}} KN<7>155 156void the_end() {}157// CHECK: `-FunctionDecl {{.*}} the_end 'void ()'158