diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 3ad01bdca20..e4b1d5ca66c 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -6412,6 +6412,45 @@ static void handleOpenCLAccessAttr(Sema &S, Decl *D, const ParsedAttr &AL) { D->addAttr(::new (S.Context) OpenCLAccessAttr(S.Context, AL)); } +static void handleSYCLKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + // The 'sycl_kernel' attribute applies only to function templates. + const auto *FD = cast<FunctionDecl>(D); + const FunctionTemplateDecl *FT = FD->getDescribedFunctionTemplate(); + assert(FT && "Function template is expected"); + + // Function template must have at least two template parameters. + const TemplateParameterList *TL = FT->getTemplateParameters(); + if (TL->size() < 2) { + S.Diag(FT->getLocation(), diag::warn_sycl_kernel_num_of_template_params); + return; + } + + // Template parameters must be typenames. + for (unsigned I = 0; I < 2; ++I) { + const NamedDecl *TParam = TL->getParam(I); + if (isa<NonTypeTemplateParmDecl>(TParam)) { + S.Diag(FT->getLocation(), + diag::warn_sycl_kernel_invalid_template_param_type); + return; + } + } + + // Function must have at least one argument. + if (getFunctionOrMethodNumParams(D) != 1) { + S.Diag(FT->getLocation(), diag::warn_sycl_kernel_num_of_function_params); + return; + } + + // Function must return void. + QualType RetTy = getFunctionOrMethodResultType(D); + if (!RetTy->isVoidType()) { + S.Diag(FT->getLocation(), diag::warn_sycl_kernel_return_type); + return; + } + + handleSimpleAttribute<SYCLKernelAttr>(S, D, AL); +} + static void handleDestroyAttr(Sema &S, Decl *D, const ParsedAttr &A) { if (!cast<VarDecl>(D)->hasGlobalStorage()) { S.Diag(D->getLocation(), diag::err_destroy_attr_on_non_static_var) @@ -6739,6 +6778,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case ParsedAttr::AT_Flatten: handleSimpleAttribute<FlattenAttr>(S, D, AL); break; + case ParsedAttr::AT_SYCLKernel: + handleSYCLKernelAttr(S, D, AL); + break; case ParsedAttr::AT_Format: handleFormatAttr(S, D, AL); break; |

