@@ -989,7 +989,8 @@ static target getAccessTarget(const ClassTemplateSpecializationDecl *AccTy) {
989
989
// Fields of kernel object must be initialized with SYCL kernel arguments so
990
990
// in the following function we extract types of kernel object fields and add it
991
991
// to the array with kernel parameters descriptors.
992
- static void buildArgTys (ASTContext &Context, CXXRecordDecl *KernelObj,
992
+ // Returns true if all arguments are successfully built.
993
+ static bool buildArgTys (ASTContext &Context, CXXRecordDecl *KernelObj,
993
994
SmallVectorImpl<ParamDesc> &ParamDescs) {
994
995
const LambdaCapture *Cpt = KernelObj->captures_begin ();
995
996
auto CreateAndAddPrmDsc = [&](const FieldDecl *Fld, const QualType &ArgType) {
@@ -1040,6 +1041,7 @@ static void buildArgTys(ASTContext &Context, CXXRecordDecl *KernelObj,
1040
1041
}
1041
1042
};
1042
1043
1044
+ bool AllArgsAreValid = true ;
1043
1045
// Run through kernel object fields and create corresponding kernel
1044
1046
// parameters descriptors. There are a several possible cases:
1045
1047
// - Kernel object field is a SYCL special object (SYCL accessor or SYCL
@@ -1054,17 +1056,22 @@ static void buildArgTys(ASTContext &Context, CXXRecordDecl *KernelObj,
1054
1056
QualType ArgTy = Fld->getType ();
1055
1057
if (Util::isSyclAccessorType (ArgTy) || Util::isSyclSamplerType (ArgTy)) {
1056
1058
createSpecialSYCLObjParamDesc (Fld, ArgTy);
1057
- } else if (ArgTy->isStructureOrClassType ()) {
1059
+ } else if (! ArgTy->isStandardLayoutType ()) {
1058
1060
// SYCL v1.2.1 s4.8.10 p5:
1059
1061
// C++ non-standard layout values must not be passed as arguments to a
1060
1062
// kernel that is compiled for a device.
1061
- if (!ArgTy->isStandardLayoutType ()) {
1062
- const DeclaratorDecl *V =
1063
- Cpt ? cast<DeclaratorDecl>(Cpt->getCapturedVar ())
1064
- : cast<DeclaratorDecl>(Fld);
1065
- KernelObj->getASTContext ().getDiagnostics ().Report (
1066
- V->getLocation (), diag::err_sycl_non_std_layout_type);
1067
- }
1063
+ const auto &DiagLocation =
1064
+ Cpt ? Cpt->getLocation () : cast<DeclaratorDecl>(Fld)->getLocation ();
1065
+
1066
+ Context.getDiagnostics ().Report (DiagLocation,
1067
+ diag::err_sycl_non_std_layout_type);
1068
+
1069
+ // Set the flag and continue processing so we can emit error for each
1070
+ // invalid argument.
1071
+ AllArgsAreValid = false ;
1072
+ } else if (ArgTy->isStructureOrClassType ()) {
1073
+ assert (ArgTy->isStandardLayoutType ());
1074
+
1068
1075
CreateAndAddPrmDsc (Fld, ArgTy);
1069
1076
1070
1077
// Create descriptors for each accessor field in the class or struct
@@ -1077,14 +1084,20 @@ static void buildArgTys(ASTContext &Context, CXXRecordDecl *KernelObj,
1077
1084
PointeeTy = Context.getQualifiedType (PointeeTy.getUnqualifiedType (),
1078
1085
Quals);
1079
1086
QualType ModTy = Context.getPointerType (PointeeTy);
1080
-
1087
+
1081
1088
CreateAndAddPrmDsc (Fld, ModTy);
1082
1089
} else if (ArgTy->isScalarType ()) {
1083
1090
CreateAndAddPrmDsc (Fld, ArgTy);
1084
1091
} else {
1085
1092
llvm_unreachable (" Unsupported kernel parameter type" );
1086
1093
}
1094
+
1095
+ // Update capture iterator as we process arguments
1096
+ if (Cpt && Cpt != KernelObj->captures_end ())
1097
+ ++Cpt;
1087
1098
}
1099
+
1100
+ return AllArgsAreValid;
1088
1101
}
1089
1102
1090
1103
// / Adds necessary data describing given kernel to the integration header.
@@ -1238,7 +1251,8 @@ void Sema::ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc,
1238
1251
1239
1252
// Build list of kernel arguments
1240
1253
llvm::SmallVector<ParamDesc, 16 > ParamDescs;
1241
- buildArgTys (getASTContext (), LE, ParamDescs);
1254
+ if (!buildArgTys (getASTContext (), LE, ParamDescs))
1255
+ return ;
1242
1256
1243
1257
// Extract name from kernel caller parameters and mangle it.
1244
1258
const TemplateArgumentList *TemplateArgs =
0 commit comments