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 %s 5 // 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 %s 8 // 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 %s 12 // 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 %s 16 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-host \ 17 // RUN: -emit-pch -o %t %s 18 // 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 %s 22 23 // These tests validate the AST body produced for functions declared with the 24 // sycl_kernel_entry_point attribute. 25 26 // CHECK: TranslationUnitDecl {{.*}} 27 28 // A unique kernel name type is required for each declared kernel entry point. 29 template<int> struct KN; 30 31 // A unique invocable type for use with each declared kernel entry point. 32 template<int> struct K { 33 template<typename... Ts> 34 void operator()(Ts...) const {} 35 }; 36 37 38 [[clang::sycl_kernel_entry_point(KN<1>)]] 39 void skep1() { 40 } 41 // CHECK: |-FunctionDecl {{.*}} skep1 'void ()' 42 // CHECK-NEXT: | |-SYCLKernelCallStmt {{.*}} 43 // CHECK-NEXT: | | |-CompoundStmt {{.*}} 44 // CHECK-NEXT: | | `-OutlinedFunctionDecl {{.*}} 45 // CHECK-NEXT: | | `-CompoundStmt {{.*}} 46 // CHECK-NEXT: | `-SYCLKernelEntryPointAttr {{.*}} KN<1> 47 48 template<typename KNT, typename KT> 49 [[clang::sycl_kernel_entry_point(KNT)]] 50 void skep2(KT k) { 51 k(); 52 } 53 template 54 void skep2<KN<2>>(K<2>); 55 // CHECK: |-FunctionTemplateDecl {{.*}} skep2 56 // CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} KNT 57 // CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} KT 58 // CHECK-NEXT: | |-FunctionDecl {{.*}} skep2 'void (KT)' 59 // CHECK-NEXT: | | |-ParmVarDecl {{.*}} k 'KT' 60 // CHECK-NEXT: | | |-CompoundStmt {{.*}} 61 // CHECK-NEXT: | | | `-CallExpr {{.*}} '<dependent type>' 62 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'KT' lvalue ParmVar {{.*}} 'k' 'KT' 63 // CHECK-NEXT: | | `-SYCLKernelEntryPointAttr {{.*}} KNT 64 65 // CHECK-NEXT: | `-FunctionDecl {{.*}} skep2 'void (K<2>)' explicit_instantiation_definition 66 // CHECK-NEXT: | |-TemplateArgument type 'KN<2>' 67 // CHECK-NEXT: | | `-RecordType {{.*}} 'KN<2>' 68 // CHECK-NEXT: | | `-ClassTemplateSpecialization {{.*}} 'KN' 69 // CHECK-NEXT: | |-TemplateArgument type 'K<2>' 70 // CHECK-NEXT: | | `-RecordType {{.*}} 'K<2>' 71 // CHECK-NEXT: | | `-ClassTemplateSpecialization {{.*}} 'K' 72 // CHECK-NEXT: | |-ParmVarDecl {{.*}} k 'K<2>' 73 // CHECK-NEXT: | |-SYCLKernelCallStmt {{.*}} 74 // CHECK-NEXT: | | |-CompoundStmt {{.*}} 75 // CHECK-NEXT: | | | `-CXXOperatorCallExpr {{.*}} 'void' '()' 76 // CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'void (*)() const' <FunctionToPointerDecay> 77 // CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'void () const' lvalue CXXMethod {{.*}} 'operator()' 'void () const' 78 // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const K<2>' lvalue <NoOp> 79 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'K<2>' lvalue ParmVar {{.*}} 'k' 'K<2>' 80 // CHECK-NEXT: | | `-OutlinedFunctionDecl {{.*}} 81 // CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} implicit used k 'K<2>' 82 // CHECK-NEXT: | | `-CompoundStmt {{.*}} 83 // CHECK-NEXT: | | `-CXXOperatorCallExpr {{.*}} 'void' '()' 84 // CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'void (*)() const' <FunctionToPointerDecay> 85 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'void () const' lvalue CXXMethod {{.*}} 'operator()' 'void () const' 86 // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const K<2>' lvalue <NoOp> 87 // CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'K<2>' lvalue ImplicitParam {{.*}} 'k' 'K<2>' 88 // CHECK-NEXT: | `-SYCLKernelEntryPointAttr {{.*}} KN<2> 89 90 template<typename KNT, typename KT> 91 [[clang::sycl_kernel_entry_point(KNT)]] 92 void skep3(KT k) { 93 k(); 94 } 95 template<> 96 [[clang::sycl_kernel_entry_point(KN<3>)]] 97 void skep3<KN<3>>(K<3> k) { 98 k(); 99 } 100 // CHECK: |-FunctionTemplateDecl {{.*}} skep3 101 // CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} KNT 102 // CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} KT 103 // CHECK-NEXT: | |-FunctionDecl {{.*}} skep3 'void (KT)' 104 // CHECK-NEXT: | | |-ParmVarDecl {{.*}} k 'KT' 105 // CHECK-NEXT: | | |-CompoundStmt {{.*}} 106 // CHECK-NEXT: | | | `-CallExpr {{.*}} '<dependent type>' 107 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'KT' lvalue ParmVar {{.*}} 'k' 'KT' 108 // CHECK-NEXT: | | `-SYCLKernelEntryPointAttr {{.*}} KNT 109 110 // CHECK-NEXT: | `-Function {{.*}} 'skep3' 'void (K<3>)' 111 // CHECK-NEXT: |-FunctionDecl {{.*}} skep3 'void (K<3>)' explicit_specialization 112 // CHECK-NEXT: | |-TemplateArgument type 'KN<3>' 113 // CHECK-NEXT: | | `-RecordType {{.*}} 'KN<3>' 114 // CHECK-NEXT: | | `-ClassTemplateSpecialization {{.*}} 'KN' 115 // CHECK-NEXT: | |-TemplateArgument type 'K<3>' 116 // CHECK-NEXT: | | `-RecordType {{.*}} 'K<3>' 117 // CHECK-NEXT: | | `-ClassTemplateSpecialization {{.*}} 'K' 118 // CHECK-NEXT: | |-ParmVarDecl {{.*}} k 'K<3>' 119 // CHECK-NEXT: | |-SYCLKernelCallStmt {{.*}} 120 // CHECK-NEXT: | | |-CompoundStmt {{.*}} 121 // CHECK-NEXT: | | | `-CXXOperatorCallExpr {{.*}} 'void' '()' 122 // CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'void (*)() const' <FunctionToPointerDecay> 123 // CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'void () const' lvalue CXXMethod {{.*}} 'operator()' 'void () const' 124 // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const K<3>' lvalue <NoOp> 125 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'K<3>' lvalue ParmVar {{.*}} 'k' 'K<3>' 126 // CHECK-NEXT: | | `-OutlinedFunctionDecl {{.*}} 127 // CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} implicit used k 'K<3>' 128 // CHECK-NEXT: | | `-CompoundStmt {{.*}} 129 // CHECK-NEXT: | | `-CXXOperatorCallExpr {{.*}} 'void' '()' 130 // CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'void (*)() const' <FunctionToPointerDecay> 131 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'void () const' lvalue CXXMethod {{.*}} 'operator()' 'void () const' 132 // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const K<3>' lvalue <NoOp> 133 // CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'K<3>' lvalue ImplicitParam {{.*}} 'k' 'K<3>' 134 // CHECK-NEXT: | `-SYCLKernelEntryPointAttr {{.*}} KN<3> 135 136 [[clang::sycl_kernel_entry_point(KN<4>)]] 137 void skep4(K<4> k, int p1, int p2) { 138 k(p1, p2); 139 } 140 // CHECK: |-FunctionDecl {{.*}} skep4 'void (K<4>, int, int)' 141 // CHECK-NEXT: | |-ParmVarDecl {{.*}} k 'K<4>' 142 // CHECK-NEXT: | |-ParmVarDecl {{.*}} p1 'int' 143 // CHECK-NEXT: | |-ParmVarDecl {{.*}} p2 'int' 144 // CHECK-NEXT: | |-SYCLKernelCallStmt {{.*}} 145 // CHECK-NEXT: | | |-CompoundStmt {{.*}} 146 // CHECK-NEXT: | | | `-CXXOperatorCallExpr {{.*}} 'void' '()' 147 // CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'void (*)(int, int) const' <FunctionToPointerDecay> 148 // CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'void (int, int) const' lvalue CXXMethod {{.*}} 'operator()' 'void (int, int) const' 149 // CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'const K<4>' lvalue <NoOp> 150 // CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'K<4>' lvalue ParmVar {{.*}} 'k' 'K<4>' 151 // CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'int' <LValueToRValue> 152 // CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'p1' 'int' 153 // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'int' <LValueToRValue> 154 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'p2' 'int' 155 // CHECK-NEXT: | | `-OutlinedFunctionDecl {{.*}} 156 // CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} implicit used k 'K<4>' 157 // CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} implicit used p1 'int' 158 // CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} implicit used p2 'int' 159 // CHECK-NEXT: | | `-CompoundStmt {{.*}} 160 // CHECK-NEXT: | | `-CXXOperatorCallExpr {{.*}} 'void' '()' 161 // CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'void (*)(int, int) const' <FunctionToPointerDecay> 162 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'void (int, int) const' lvalue CXXMethod {{.*}} 'operator()' 'void (int, int) const' 163 // CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'const K<4>' lvalue <NoOp> 164 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'K<4>' lvalue ImplicitParam {{.*}} 'k' 'K<4>' 165 // CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'int' <LValueToRValue> 166 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'int' lvalue ImplicitParam {{.*}} 'p1' 'int' 167 // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'int' <LValueToRValue> 168 // CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'int' lvalue ImplicitParam {{.*}} 'p2' 'int' 169 // CHECK-NEXT: | `-SYCLKernelEntryPointAttr {{.*}} KN<4> 170 171 [[clang::sycl_kernel_entry_point(KN<5>)]] 172 void skep5(int unused1, K<5> k, int unused2, int p, int unused3) { 173 static int slv = 0; 174 int lv = 4; 175 k(slv, 1, p, 3, lv, 5, []{ return 6; }); 176 } 177 // CHECK: |-FunctionDecl {{.*}} skep5 'void (int, K<5>, int, int, int)' 178 // CHECK-NEXT: | |-ParmVarDecl {{.*}} unused1 'int' 179 // CHECK-NEXT: | |-ParmVarDecl {{.*}} used k 'K<5>' 180 // CHECK-NEXT: | |-ParmVarDecl {{.*}} unused2 'int' 181 // CHECK-NEXT: | |-ParmVarDecl {{.*}} used p 'int' 182 // CHECK-NEXT: | |-ParmVarDecl {{.*}} unused3 'int' 183 // CHECK-NEXT: | |-SYCLKernelCallStmt {{.*}} 184 // CHECK-NEXT: | | |-CompoundStmt {{.*}} 185 // CHECK: | | `-OutlinedFunctionDecl {{.*}} 186 // CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} implicit unused1 'int' 187 // CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} implicit used k 'K<5>' 188 // CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} implicit unused2 'int' 189 // CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} implicit used p 'int' 190 // CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} implicit unused3 'int' 191 // CHECK-NEXT: | | `-CompoundStmt {{.*}} 192 // CHECK-NEXT: | | |-DeclStmt {{.*}} 193 // CHECK-NEXT: | | | `-VarDecl {{.*}} used slv 'int' static cinit 194 // CHECK-NEXT: | | | `-IntegerLiteral {{.*}} 'int' 0 195 // CHECK-NEXT: | | |-DeclStmt {{.*}} 196 // CHECK-NEXT: | | | `-VarDecl {{.*}} used lv 'int' cinit 197 // CHECK-NEXT: | | | `-IntegerLiteral {{.*}} 'int' 4 198 // CHECK-NEXT: | | `-CXXOperatorCallExpr {{.*}} 'void' '()' 199 // CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'void (*)(int, int, int, int, int, int, (lambda {{.*}}) const' <FunctionToPointerDecay> 200 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'void (int, int, int, int, int, int, (lambda {{.*}})) const' lvalue CXXMethod {{.*}} 'operator()' 'void (int, int, int, int, int, int, (lambda {{.*}})) const' 201 // CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'const K<5>' lvalue <NoOp> 202 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'K<5>' lvalue ImplicitParam {{.*}} 'k' 'K<5>' 203 // CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'int' <LValueToRValue> 204 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'slv' 'int' 205 // CHECK-NEXT: | | |-IntegerLiteral {{.*}} 'int' 1 206 // CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'int' <LValueToRValue> 207 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'int' lvalue ImplicitParam {{.*}} 'p' 'int' 208 // CHECK-NEXT: | | |-IntegerLiteral {{.*}} 'int' 3 209 // CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'int' <LValueToRValue> 210 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'lv' 'int' 211 // CHECK-NEXT: | | |-IntegerLiteral {{.*}} 'int' 5 212 // CHECK-NEXT: | | `-LambdaExpr {{.*}} '(lambda {{.*}})' 213 // CHECK: | `-SYCLKernelEntryPointAttr {{.*}} KN<5> 214 215 struct S6 { 216 void operator()() const; 217 }; 218 [[clang::sycl_kernel_entry_point(KN<6>)]] 219 void skep6(const S6 &k) { 220 k(); 221 } 222 // CHECK: |-FunctionDecl {{.*}} skep6 'void (const S6 &)' 223 // CHECK-NEXT: | |-ParmVarDecl {{.*}} used k 'const S6 &' 224 // CHECK-NEXT: | |-SYCLKernelCallStmt {{.*}} 225 // CHECK-NEXT: | | |-CompoundStmt {{.*}} 226 // CHECK-NEXT: | | | `-CXXOperatorCallExpr {{.*}} 'void' '()' 227 // CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'void (*)() const' <FunctionToPointerDecay> 228 // CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'void () const' lvalue CXXMethod {{.*}} 'operator()' 'void () const' 229 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'const S6' lvalue ParmVar {{.*}} 'k' 'const S6 &' 230 // CHECK-NEXT: | | `-OutlinedFunctionDecl {{.*}} 231 // CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} implicit used k 'const S6 &' 232 // CHECK-NEXT: | | `-CompoundStmt {{.*}} 233 // CHECK-NEXT: | | `-CXXOperatorCallExpr {{.*}} 'void' '()' 234 // CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'void (*)() const' <FunctionToPointerDecay> 235 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'void () const' lvalue CXXMethod {{.*}} 'operator()' 'void () const' 236 // CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'const S6' lvalue ImplicitParam {{.*}} 'k' 'const S6 &' 237 // CHECK-NEXT: | `-SYCLKernelEntryPointAttr {{.*}} KN<6> 238 239 // Parameter types are not required to be complete at the point of a 240 // non-defining declaration. 241 struct S7; 242 [[clang::sycl_kernel_entry_point(KN<7>)]] 243 void skep7(S7 k); 244 struct S7 { 245 void operator()() const; 246 }; 247 [[clang::sycl_kernel_entry_point(KN<7>)]] 248 void skep7(S7 k) { 249 k(); 250 } 251 // CHECK: |-FunctionDecl {{.*}} skep7 'void (S7)' 252 // CHECK-NEXT: | |-ParmVarDecl {{.*}} k 'S7' 253 // CHECK-NEXT: | `-SYCLKernelEntryPointAttr {{.*}} KN<7> 254 // CHECK: |-FunctionDecl {{.*}} prev {{.*}} skep7 'void (S7)' 255 // CHECK-NEXT: | |-ParmVarDecl {{.*}} used k 'S7' 256 // CHECK-NEXT: | |-SYCLKernelCallStmt {{.*}} 257 // CHECK-NEXT: | | |-CompoundStmt {{.*}} 258 // CHECK-NEXT: | | | `-CXXOperatorCallExpr {{.*}} 'void' '()' 259 // CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'void (*)() const' <FunctionToPointerDecay> 260 // CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'void () const' lvalue CXXMethod {{.*}} 'operator()' 'void () const' 261 // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const S7' lvalue <NoOp> 262 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'S7' lvalue ParmVar {{.*}} 'k' 'S7' 263 // CHECK-NEXT: | | `-OutlinedFunctionDecl {{.*}} 264 // CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} implicit used k 'S7' 265 // CHECK-NEXT: | | `-CompoundStmt {{.*}} 266 // CHECK-NEXT: | | `-CXXOperatorCallExpr {{.*}} 'void' '()' 267 // CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'void (*)() const' <FunctionToPointerDecay> 268 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'void () const' lvalue CXXMethod {{.*}} 'operator()' 'void () const' 269 // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const S7' lvalue <NoOp> 270 // CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'S7' lvalue ImplicitParam {{.*}} 'k' 'S7' 271 // CHECK-NEXT: | `-SYCLKernelEntryPointAttr {{.*}} KN<7> 272 273 274 void the_end() {} 275 // CHECK: `-FunctionDecl {{.*}} the_end 'void ()' 276