@@ -706,7 +706,8 @@ getKernelInvocationKind(FunctionDecl *KernelCallerFunc) {
706
706
}
707
707
708
708
static const CXXRecordDecl *getKernelObjectType (FunctionDecl *Caller) {
709
- return (*Caller->param_begin ())->getType ()->getAsCXXRecordDecl ();
709
+ assert (Caller->getNumParams () > 0 && " Insufficient kernel parameters" );
710
+ return Caller->getParamDecl (0 )->getType ()->getAsCXXRecordDecl ();
710
711
}
711
712
712
713
// / Creates a kernel parameter descriptor
@@ -1205,7 +1206,6 @@ class SyclKernelFieldChecker : public SyclKernelFieldHandler {
1205
1206
class SyclKernelDeclCreator : public SyclKernelFieldHandler {
1206
1207
FunctionDecl *KernelDecl;
1207
1208
llvm::SmallVector<ParmVarDecl *, 8 > Params;
1208
- SyclKernelFieldChecker &ArgChecker;
1209
1209
Sema::ContextRAII FuncContext;
1210
1210
// Holds the last handled field's first parameter. This doesn't store an
1211
1211
// iterator as push_back invalidates iterators.
@@ -1339,13 +1339,12 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {
1339
1339
}
1340
1340
1341
1341
public:
1342
- SyclKernelDeclCreator (Sema &S, SyclKernelFieldChecker &ArgChecker,
1343
- StringRef Name, SourceLocation Loc, bool IsInline,
1344
- bool IsSIMDKernel)
1342
+ SyclKernelDeclCreator (Sema &S, StringRef Name, SourceLocation Loc,
1343
+ bool IsInline, bool IsSIMDKernel)
1345
1344
: SyclKernelFieldHandler(S),
1346
1345
KernelDecl (createKernelDecl(S.getASTContext(), Name, Loc, IsInline,
1347
1346
IsSIMDKernel)),
1348
- ArgChecker(ArgChecker), FuncContext(SemaRef, KernelDecl) {}
1347
+ FuncContext(SemaRef, KernelDecl) {}
1349
1348
1350
1349
~SyclKernelDeclCreator () {
1351
1350
ASTContext &Ctx = SemaRef.getASTContext ();
@@ -1360,8 +1359,7 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {
1360
1359
KernelDecl->setType (FuncType);
1361
1360
KernelDecl->setParams (Params);
1362
1361
1363
- if (ArgChecker.isValid ())
1364
- SemaRef.addSyclDeviceDecl (KernelDecl);
1362
+ SemaRef.addSyclDeviceDecl (KernelDecl);
1365
1363
}
1366
1364
1367
1365
bool handleSyclAccessorType (const CXXBaseSpecifier &BS,
@@ -2015,8 +2013,38 @@ class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler {
2015
2013
using SyclKernelFieldHandler::handleSyclHalfType;
2016
2014
using SyclKernelFieldHandler::handleSyclSamplerType;
2017
2015
};
2016
+
2018
2017
} // namespace
2019
2018
2019
+ void Sema::CheckSYCLKernelCall (FunctionDecl *KernelFunc, SourceRange CallLoc,
2020
+ ArrayRef<const Expr *> Args) {
2021
+ const CXXRecordDecl *KernelObj = getKernelObjectType (KernelFunc);
2022
+ if (!KernelObj) {
2023
+ Diag (Args[0 ]->getExprLoc (), diag::err_sycl_kernel_not_function_object);
2024
+ KernelFunc->setInvalidDecl ();
2025
+ return ;
2026
+ }
2027
+
2028
+ if (KernelObj->isLambda ()) {
2029
+ for (const LambdaCapture &LC : KernelObj->captures ())
2030
+ if (LC.capturesThis () && LC.isImplicit ()) {
2031
+ Diag (LC.getLocation (), diag::err_implicit_this_capture);
2032
+ Diag (CallLoc.getBegin (), diag::note_used_here);
2033
+ KernelFunc->setInvalidDecl ();
2034
+ }
2035
+ }
2036
+
2037
+ SyclKernelFieldChecker Checker (*this );
2038
+
2039
+ KernelObjVisitor Visitor{*this };
2040
+ DiagnosingSYCLKernel = true ;
2041
+ Visitor.VisitRecordBases (KernelObj, Checker);
2042
+ Visitor.VisitRecordFields (KernelObj, Checker);
2043
+ DiagnosingSYCLKernel = false ;
2044
+ if (!Checker.isValid ())
2045
+ KernelFunc->setInvalidDecl ();
2046
+ }
2047
+
2020
2048
// Generates the OpenCL kernel using KernelCallerFunc (kernel caller
2021
2049
// function) defined is SYCL headers.
2022
2050
// Generated OpenCL kernel contains the body of the kernel caller function,
@@ -2051,29 +2079,19 @@ void Sema::ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc,
2051
2079
constructKernelName (*this , KernelCallerFunc, MC);
2052
2080
StringRef KernelName (getLangOpts ().SYCLUnnamedLambda ? StableName
2053
2081
: CalculatedName);
2054
- if (KernelObj->isLambda ()) {
2055
- for (const LambdaCapture &LC : KernelObj->captures ())
2056
- if (LC.capturesThis () && LC.isImplicit ())
2057
- Diag (LC.getLocation (), diag::err_implicit_this_capture);
2058
- }
2059
- SyclKernelFieldChecker checker (*this );
2060
- SyclKernelDeclCreator kernel_decl (
2061
- *this , checker, KernelName, KernelObj->getLocation (),
2062
- KernelCallerFunc->isInlined (), KernelCallerFunc->hasAttr <SYCLSimdAttr>());
2082
+ SyclKernelDeclCreator kernel_decl (*this , KernelName, KernelObj->getLocation (),
2083
+ KernelCallerFunc->isInlined (),
2084
+ KernelCallerFunc->hasAttr <SYCLSimdAttr>());
2063
2085
SyclKernelBodyCreator kernel_body (*this , kernel_decl, KernelObj,
2064
2086
KernelCallerFunc);
2065
2087
SyclKernelIntHeaderCreator int_header (
2066
2088
*this , getSyclIntegrationHeader (), KernelObj,
2067
2089
calculateKernelNameType (Context, KernelCallerFunc), KernelName,
2068
2090
StableName);
2069
2091
2070
- ConstructingOpenCLKernel = true ;
2071
2092
KernelObjVisitor Visitor{*this };
2072
- Visitor.VisitRecordBases (KernelObj, checker, kernel_decl, kernel_body,
2073
- int_header);
2074
- Visitor.VisitRecordFields (KernelObj, checker, kernel_decl, kernel_body,
2075
- int_header);
2076
- ConstructingOpenCLKernel = false ;
2093
+ Visitor.VisitRecordBases (KernelObj, kernel_decl, kernel_body, int_header);
2094
+ Visitor.VisitRecordFields (KernelObj, kernel_decl, kernel_body, int_header);
2077
2095
}
2078
2096
2079
2097
// This function marks all the callees of explicit SIMD kernel
@@ -2242,7 +2260,7 @@ Sema::DeviceDiagBuilder Sema::SYCLDiagIfDeviceCode(SourceLocation Loc,
2242
2260
" Should only be called during SYCL compilation" );
2243
2261
FunctionDecl *FD = dyn_cast<FunctionDecl>(getCurLexicalContext ());
2244
2262
DeviceDiagBuilder::Kind DiagKind = [this , FD] {
2245
- if (ConstructingOpenCLKernel )
2263
+ if (DiagnosingSYCLKernel )
2246
2264
return DeviceDiagBuilder::K_ImmediateWithCallStack;
2247
2265
if (!FD)
2248
2266
return DeviceDiagBuilder::K_Nop;
0 commit comments