@@ -85,6 +85,10 @@ class Util {
85
85
// / property_list class.
86
86
static bool isPropertyListType (const QualType &Ty);
87
87
88
+ // / Checks whether given clang type is a full specialization of the SYCL
89
+ // / accessor_property_list class.
90
+ static bool isAccessorPropertyListType (const QualType &Ty);
91
+
88
92
// / Checks whether given clang type is a full specialization of the SYCL
89
93
// / buffer_location class.
90
94
static bool isSyclBufferLocationType (const QualType &Ty);
@@ -1194,29 +1198,33 @@ class SyclKernelFieldChecker : public SyclKernelFieldHandler {
1194
1198
return ;
1195
1199
}
1196
1200
QualType PropListTy = PropList.getAsType ();
1197
- if (!Util::isPropertyListType (PropListTy)) {
1201
+ if (Util::isPropertyListType (PropListTy))
1202
+ return ;
1203
+ if (!Util::isAccessorPropertyListType (PropListTy)) {
1198
1204
SemaRef.Diag (Loc,
1199
1205
diag::err_sycl_invalid_accessor_property_template_param);
1200
1206
return ;
1201
1207
}
1202
- const auto *PropListDecl =
1208
+ const auto *AccPropListDecl =
1203
1209
cast<ClassTemplateSpecializationDecl>(PropListTy->getAsRecordDecl ());
1204
- if (PropListDecl ->getTemplateArgs ().size () != 1 ) {
1210
+ if (AccPropListDecl ->getTemplateArgs ().size () != 1 ) {
1205
1211
SemaRef.Diag (Loc, diag::err_sycl_invalid_property_list_param_number)
1206
- << " property_list " ;
1212
+ << " accessor_property_list " ;
1207
1213
return ;
1208
1214
}
1209
- const auto TemplArg = PropListDecl ->getTemplateArgs ()[0 ];
1215
+ const auto TemplArg = AccPropListDecl ->getTemplateArgs ()[0 ];
1210
1216
if (TemplArg.getKind () != TemplateArgument::ArgKind::Pack) {
1211
- SemaRef.Diag (Loc, diag::err_sycl_invalid_property_list_template_param)
1212
- << /* property_list*/ 0 << /* parameter pack*/ 0 ;
1217
+ SemaRef.Diag (Loc,
1218
+ diag::err_sycl_invalid_accessor_property_list_template_param)
1219
+ << /* accessor_property_list*/ 0 << /* parameter pack*/ 0 ;
1213
1220
return ;
1214
1221
}
1215
1222
for (TemplateArgument::pack_iterator Prop = TemplArg.pack_begin ();
1216
1223
Prop != TemplArg.pack_end (); ++Prop) {
1217
1224
if (Prop->getKind () != TemplateArgument::ArgKind::Type) {
1218
- SemaRef.Diag (Loc, diag::err_sycl_invalid_property_list_template_param)
1219
- << /* property_list pack argument*/ 1 << /* type*/ 1 ;
1225
+ SemaRef.Diag (
1226
+ Loc, diag::err_sycl_invalid_accessor_property_list_template_param)
1227
+ << /* accessor_property_list pack argument*/ 1 << /* type*/ 1 ;
1220
1228
return ;
1221
1229
}
1222
1230
QualType PropTy = Prop->getAsType ();
@@ -1235,13 +1243,15 @@ class SyclKernelFieldChecker : public SyclKernelFieldHandler {
1235
1243
}
1236
1244
const auto BufferLoc = PropDecl->getTemplateArgs ()[0 ];
1237
1245
if (BufferLoc.getKind () != TemplateArgument::ArgKind::Integral) {
1238
- SemaRef.Diag (Loc, diag::err_sycl_invalid_property_list_template_param)
1246
+ SemaRef.Diag (Loc,
1247
+ diag::err_sycl_invalid_accessor_property_list_template_param)
1239
1248
<< /* buffer_location*/ 2 << /* non-negative integer*/ 2 ;
1240
1249
return ;
1241
1250
}
1242
1251
int LocationID = static_cast <int >(BufferLoc.getAsIntegral ().getExtValue ());
1243
1252
if (LocationID < 0 ) {
1244
- SemaRef.Diag (Loc, diag::err_sycl_invalid_property_list_template_param)
1253
+ SemaRef.Diag (Loc,
1254
+ diag::err_sycl_invalid_accessor_property_list_template_param)
1245
1255
<< /* buffer_location*/ 2 << /* non-negative integer*/ 2 ;
1246
1256
return ;
1247
1257
}
@@ -1251,17 +1261,29 @@ class SyclKernelFieldChecker : public SyclKernelFieldHandler {
1251
1261
assert (Util::isSyclAccessorType (Ty) &&
1252
1262
" Should only be called on SYCL accessor types." );
1253
1263
1254
- const RecordDecl *RecD = Ty->getAsRecordDecl ();
1255
- if (const ClassTemplateSpecializationDecl *CTSD =
1256
- dyn_cast<ClassTemplateSpecializationDecl>(RecD)) {
1264
+ RecordDecl *RecD = Ty->getAsRecordDecl ();
1265
+ if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RecD)) {
1257
1266
const TemplateArgumentList &TAL = CTSD->getTemplateArgs ();
1267
+
1258
1268
TemplateArgument TA = TAL.get (0 );
1259
1269
const QualType TemplateArgTy = TA.getAsType ();
1260
-
1261
- if (TAL.size () > 5 )
1262
- checkPropertyListType (TAL.get (5 ), Loc.getBegin ());
1263
1270
llvm::DenseSet<QualType> Visited;
1264
1271
checkSYCLType (SemaRef, TemplateArgTy, Loc, Visited);
1272
+
1273
+ if (TAL.size () < 6 ) {
1274
+ // Not enough arguments for this parameter pack.
1275
+ SemaRef.Diag (Loc.getBegin (),
1276
+ diag::err_template_arg_list_different_arity)
1277
+ << /* not enough args*/ 0
1278
+ << (int )SemaRef.getTemplateNameKindForDiagnostics (
1279
+ TemplateName (CTSD->getSpecializedTemplate ()))
1280
+ << CTSD;
1281
+ SemaRef.Diag (CTSD->getLocation (), diag::note_template_decl_here)
1282
+ << CTSD->getSourceRange ();
1283
+ return ;
1284
+ }
1285
+
1286
+ checkPropertyListType (TAL.get (5 ), Loc.getBegin ());
1265
1287
}
1266
1288
}
1267
1289
@@ -1402,19 +1424,21 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {
1402
1424
}
1403
1425
1404
1426
// Handle accessor properties. If any properties were found in
1405
- // the property_list - add the appropriate attributes to ParmVarDecl.
1427
+ // the accessor_property_list - add the appropriate attributes to ParmVarDecl.
1406
1428
void handleAccessorPropertyList (ParmVarDecl *Param,
1407
1429
const CXXRecordDecl *RecordDecl,
1408
1430
SourceLocation Loc) {
1409
1431
const auto *AccTy = cast<ClassTemplateSpecializationDecl>(RecordDecl);
1410
- // TODO: when SYCL headers' part is ready - replace this 'if' with an error
1411
1432
if (AccTy->getTemplateArgs ().size () < 6 )
1412
1433
return ;
1413
1434
const auto PropList = cast<TemplateArgument>(AccTy->getTemplateArgs ()[5 ]);
1414
1435
QualType PropListTy = PropList.getAsType ();
1415
- const auto *PropListDecl =
1436
+ // property_list contains runtime properties, it shouldn't be handled here.
1437
+ if (Util::isPropertyListType (PropListTy))
1438
+ return ;
1439
+ const auto *AccPropListDecl =
1416
1440
cast<ClassTemplateSpecializationDecl>(PropListTy->getAsRecordDecl ());
1417
- const auto TemplArg = PropListDecl ->getTemplateArgs ()[0 ];
1441
+ const auto TemplArg = AccPropListDecl ->getTemplateArgs ()[0 ];
1418
1442
// Move through TemplateArgs list of a property list and search for
1419
1443
// properties. If found - apply the appropriate attribute to ParmVarDecl.
1420
1444
for (TemplateArgument::pack_iterator Prop = TemplArg.pack_begin ();
@@ -3444,17 +3468,16 @@ bool Util::isSyclSpecConstantType(const QualType &Ty) {
3444
3468
}
3445
3469
3446
3470
bool Util::isPropertyListType (const QualType &Ty) {
3447
- return isSyclType (Ty, " property_list" , true /* Tmpl */ );
3471
+ return isSyclType (Ty, " property_list" );
3448
3472
}
3449
3473
3450
3474
bool Util::isSyclBufferLocationType (const QualType &Ty) {
3451
3475
const StringRef &Name = " buffer_location" ;
3452
- std::array<DeclContextDesc, 4 > Scopes = {
3476
+ std::array<DeclContextDesc, 6 > Scopes = {
3453
3477
Util::DeclContextDesc{clang::Decl::Kind::Namespace, " cl" },
3454
3478
Util::DeclContextDesc{clang::Decl::Kind::Namespace, " sycl" },
3455
- // TODO: this doesn't belong to property namespace, instead it shall be
3456
- // in its own namespace. Change it, when the actual implementation in SYCL
3457
- // headers is ready
3479
+ Util::DeclContextDesc{clang::Decl::Kind::Namespace, " ext" },
3480
+ Util::DeclContextDesc{clang::Decl::Kind::Namespace, " INTEL" },
3458
3481
Util::DeclContextDesc{clang::Decl::Kind::Namespace, " property" },
3459
3482
Util::DeclContextDesc{Decl::Kind::ClassTemplateSpecialization, Name}};
3460
3483
return matchQualifiedTypeName (Ty, Scopes);
@@ -3470,6 +3493,17 @@ bool Util::isSyclType(const QualType &Ty, StringRef Name, bool Tmpl) {
3470
3493
return matchQualifiedTypeName (Ty, Scopes);
3471
3494
}
3472
3495
3496
+ bool Util::isAccessorPropertyListType (const QualType &Ty) {
3497
+ const StringRef &Name = " accessor_property_list" ;
3498
+ std::array<DeclContextDesc, 5 > Scopes = {
3499
+ Util::DeclContextDesc{clang::Decl::Kind::Namespace, " cl" },
3500
+ Util::DeclContextDesc{clang::Decl::Kind::Namespace, " sycl" },
3501
+ Util::DeclContextDesc{clang::Decl::Kind::Namespace, " ext" },
3502
+ Util::DeclContextDesc{clang::Decl::Kind::Namespace, " ONEAPI" },
3503
+ Util::DeclContextDesc{Decl::Kind::ClassTemplateSpecialization, Name}};
3504
+ return matchQualifiedTypeName (Ty, Scopes);
3505
+ }
3506
+
3473
3507
bool Util::matchQualifiedTypeName (const QualType &Ty,
3474
3508
ArrayRef<Util::DeclContextDesc> Scopes) {
3475
3509
// The idea: check the declaration context chain starting from the type
0 commit comments