@@ -698,7 +698,38 @@ getKernelInvocationKind(FunctionDecl *KernelCallerFunc) {
698698}
699699
700700static 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+ }
702733}
703734
704735// / Creates a kernel parameter descriptor
@@ -1913,11 +1944,8 @@ void Sema::ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc,
19131944 constructKernelName (*this , KernelCallerFunc, MC);
19141945 StringRef KernelName (getLangOpts ().SYCLUnnamedLambda ? StableName
19151946 : 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);
19211949 SyclKernelFieldChecker checker (*this );
19221950 SyclKernelDeclCreator kernel_decl (
19231951 *this , checker, KernelName, KernelObj->getLocation (),
0 commit comments