@@ -698,7 +698,38 @@ getKernelInvocationKind(FunctionDecl *KernelCallerFunc) {
698
698
}
699
699
700
700
static const CXXRecordDecl *getKernelObjectType (FunctionDecl *Caller) {
701
- return (*Caller->param_begin ())->getType ()->getAsCXXRecordDecl ();
701
+ QualType KernelParamTy = (*Caller->param_begin ())->getType ();
702
+ // In SYCL 2020 kernels are now passed by reference.
703
+ if (KernelParamTy->isReferenceType ())
704
+ return KernelParamTy->getPointeeCXXRecordDecl ();
705
+
706
+ // SYCL 1.2.1
707
+ return KernelParamTy->getAsCXXRecordDecl ();
708
+ }
709
+
710
+ static void checkKernelAndCaller (Sema &SemaRef, FunctionDecl *Caller,
711
+ const CXXRecordDecl *KernelObj) {
712
+ // check captures
713
+ if (KernelObj->isLambda ()) {
714
+ for (const LambdaCapture &LC : KernelObj->captures ())
715
+ if (LC.capturesThis () && LC.isImplicit ())
716
+ SemaRef.Diag (LC.getLocation (), diag::err_implicit_this_capture);
717
+ }
718
+
719
+ // check that calling kernel conforms to spec
720
+ assert (Caller->param_size () >= 1 && " missing kernel function argument." );
721
+ QualType KernelParamTy = (*Caller->param_begin ())->getType ();
722
+ if (KernelParamTy->isReferenceType ()) {
723
+ // passing by reference, so emit warning if not using SYCL 2020
724
+ if (SemaRef.LangOpts .SYCLVersion < 2020 )
725
+ SemaRef.Diag (Caller->getLocation (),
726
+ diag::warn_sycl_pass_by_reference_future);
727
+ } else {
728
+ // passing by value. emit warning if using SYCL 2020 or greater
729
+ if (SemaRef.LangOpts .SYCLVersion > 2017 )
730
+ SemaRef.Diag (Caller->getLocation (),
731
+ diag::warn_sycl_pass_by_value_deprecated);
732
+ }
702
733
}
703
734
704
735
// / Creates a kernel parameter descriptor
@@ -1913,11 +1944,8 @@ void Sema::ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc,
1913
1944
constructKernelName (*this , KernelCallerFunc, MC);
1914
1945
StringRef KernelName (getLangOpts ().SYCLUnnamedLambda ? StableName
1915
1946
: CalculatedName);
1916
- if (KernelObj->isLambda ()) {
1917
- for (const LambdaCapture &LC : KernelObj->captures ())
1918
- if (LC.capturesThis () && LC.isImplicit ())
1919
- Diag (LC.getLocation (), diag::err_implicit_this_capture);
1920
- }
1947
+
1948
+ checkKernelAndCaller (*this , KernelCallerFunc, KernelObj);
1921
1949
SyclKernelFieldChecker checker (*this );
1922
1950
SyclKernelDeclCreator kernel_decl (
1923
1951
*this , checker, KernelName, KernelObj->getLocation (),
0 commit comments