24 if (
getLangOpts().getOpenCLCompatibleVersion() < 200)
25 Diag(AL.
getLoc(), diag::err_attribute_requires_opencl_version)
28 Diag(AL.
getLoc(), diag::warn_opencl_attr_deprecated_ignored)
33 if (
D->isInvalidDecl())
37 if (
D->hasAttr<OpenCLAccessAttr>()) {
38 if (
D->getAttr<OpenCLAccessAttr>()->getSemanticSpelling() ==
40 Diag(AL.
getLoc(), diag::warn_duplicate_declspec)
43 Diag(AL.
getLoc(), diag::err_opencl_multiple_access_qualifiers)
44 <<
D->getSourceRange();
45 D->setInvalidDecl(
true);
59 if (
const auto *PDecl = dyn_cast<ParmVarDecl>(
D)) {
60 const Type *
DeclTy = PDecl->getType().getCanonicalType().getTypePtr();
62 bool ReadWriteImagesUnsupported =
67 if (ReadWriteImagesUnsupported ||
DeclTy->isPipeType()) {
68 Diag(AL.
getLoc(), diag::err_opencl_invalid_read_write)
69 << AL << PDecl->getType() <<
DeclTy->isImageType();
70 D->setInvalidDecl(
true);
90 unsigned ArgCounter = 0;
91 bool IllegalParams =
false;
95 I !=
E; ++I, ++ArgCounter) {
96 if (!(*I)->isPointerType() || !(*I)->getPointeeType()->isVoidType() ||
97 (*I)->getPointeeType().getQualifiers().getAddressSpace() !=
103 if (isa<BlockExpr>(BlockArg)) {
104 BlockDecl *BD = cast<BlockExpr>(BlockArg)->getBlockDecl();
106 }
else if (isa<DeclRefExpr>(BlockArg)) {
107 ErrorLoc = cast<DeclRefExpr>(BlockArg)->getBeginLoc();
110 diag::err_opencl_enqueue_kernel_blocks_non_local_void_args);
111 IllegalParams =
true;
115 return IllegalParams;
126 Diag(Call->getBeginLoc(), diag::err_opencl_requires_extension)
127 << 1 << Call->getDirectCallee()
128 <<
"cl_khr_subgroups or __opencl_c_subgroups";
144 Diag(NDRangeArg->
getBeginLoc(), diag::err_opencl_builtin_expected_type)
177 diag::err_opencl_enqueue_kernel_invalid_local_size_type);
187 unsigned Start,
unsigned End) {
188 bool IllegalParams =
false;
189 for (
unsigned I = Start; I <=
End; ++I)
192 return IllegalParams;
199 unsigned NumNonVarArgs) {
202 unsigned NumBlockParams =
204 unsigned TotalNumArgs = TheCall->
getNumArgs();
208 if (TotalNumArgs != NumBlockParams + NumNonVarArgs) {
210 diag::err_opencl_enqueue_kernel_local_size_args);
224 Diag(TheCall->
getBeginLoc(), diag::err_typecheck_call_too_few_args_at_least)
225 << 0 << 4 << NumArgs << 0;
237 diag::err_opencl_builtin_expected_type)
245 diag::err_opencl_builtin_expected_type)
246 << TheCall->
getDirectCallee() <<
"'kernel_enqueue_flags_t' (i.e. uint)";
253 diag::err_opencl_builtin_expected_type)
272 Diag(Arg3->
getBeginLoc(), diag::err_opencl_enqueue_kernel_blocks_no_args);
296 diag::err_opencl_builtin_expected_type)
309 diag::err_opencl_builtin_expected_type)
311 << Context.getPointerType(Context.OCLClkEventTy);
321 diag::err_opencl_builtin_expected_type)
323 << Context.getPointerType(Context.OCLClkEventTy);
334 Diag(TheCall->
getBeginLoc(), diag::err_opencl_enqueue_kernel_incorrect_args);
340 return D->
getAttr<OpenCLAccessAttr>();
345 const Expr *Arg0 = Call->getArg(0);
348 S.
Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_first_arg)
352 OpenCLAccessAttr *AccessQual =
358 switch (Call->getDirectCallee()->getBuiltinID()) {
359 case Builtin::BIread_pipe:
360 case Builtin::BIreserve_read_pipe:
361 case Builtin::BIcommit_read_pipe:
362 case Builtin::BIwork_group_reserve_read_pipe:
363 case Builtin::BIsub_group_reserve_read_pipe:
364 case Builtin::BIwork_group_commit_read_pipe:
365 case Builtin::BIsub_group_commit_read_pipe:
366 if (!(!AccessQual || AccessQual->isReadOnly())) {
368 diag::err_opencl_builtin_pipe_invalid_access_modifier)
373 case Builtin::BIwrite_pipe:
374 case Builtin::BIreserve_write_pipe:
375 case Builtin::BIcommit_write_pipe:
376 case Builtin::BIwork_group_reserve_write_pipe:
377 case Builtin::BIsub_group_reserve_write_pipe:
378 case Builtin::BIwork_group_commit_write_pipe:
379 case Builtin::BIsub_group_commit_write_pipe:
380 if (!(AccessQual && AccessQual->isWriteOnly())) {
382 diag::err_opencl_builtin_pipe_invalid_access_modifier)
395 const Expr *Arg0 = Call->getArg(0);
396 const Expr *ArgIdx = Call->getArg(Idx);
405 S.
Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg)
416 switch (Call->getNumArgs()) {
433 if (!Call->getArg(1)->getType()->isReserveIDT()) {
434 Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg)
436 << Call->getArg(1)->getType() << Call->getArg(1)->getSourceRange();
441 const Expr *Arg2 = Call->getArg(2);
444 Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg)
455 Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_arg_num)
456 << Call->getDirectCallee() << Call->getSourceRange();
471 if (!Call->getArg(1)->getType()->isIntegerType() &&
472 !Call->getArg(1)->getType()->isUnsignedIntegerType()) {
473 Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg)
475 << Call->getArg(1)->getType() << Call->getArg(1)->getSourceRange();
495 if (!Call->getArg(1)->getType()->isReserveIDT()) {
496 Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg)
498 << Call->getArg(1)->getType() << Call->getArg(1)->getSourceRange();
509 if (!Call->getArg(0)->getType()->isPipeType()) {
510 Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_first_arg)
511 << Call->getDirectCallee() << Call->getArg(0)->getSourceRange();
522 auto RT = Call->getArg(0)->getType();
523 if (!RT->isPointerType() ||
525 Diag(Call->getBeginLoc(), diag::err_opencl_builtin_to_addr_invalid_arg)
526 << Call->getArg(0) << Call->getDirectCallee() << Call->getSourceRange();
531 Diag(Call->getArg(0)->getBeginLoc(),
532 diag::warn_opencl_generic_address_space_arg)
533 << Call->getDirectCallee()->getNameInfo().getAsString()
534 << Call->getArg(0)->getSourceRange();
537 RT = RT->getPointeeType();
538 auto Qual = RT.getQualifiers();
540 case Builtin::BIto_global:
543 case Builtin::BIto_local:
546 case Builtin::BIto_private:
550 llvm_unreachable(
"Invalid builtin function");
553 getASTContext().getQualifiedType(RT.getUnqualifiedType(), Qual)));
This file declares semantic analysis routines for OpenCL.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
CanQualType UnsignedIntTy
CanQualType OCLReserveIDTy
SourceRange getRange() const
const IdentifierInfo * getAttrName() const
SourceLocation getLoc() const
Represents a block literal declaration, which is like an unnamed FunctionDecl.
const ParmVarDecl * getParamDecl(unsigned i) const
QualType getPointeeType() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Decl - This represents one declaration (or definition), e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
This represents one expression.
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
StringRef getName() const
Return the actual identifier string.
std::string getOpenCLVersionString() const
Return the OpenCL C or C++ for OpenCL language name and version as a string.
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
bool isSupported(llvm::StringRef Ext, const LangOptions &LO) const
ParsedAttr - Represents a syntactic attribute.
unsigned getSemanticSpelling() const
If the parsed attribute has a semantic equivalent, and it would have a semantic Spelling enumeration ...
QualType getElementType() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
bool checkBuiltinNDRangeAndBlock(CallExpr *TheCall)
bool checkBuiltinKernelWorkGroupSize(CallExpr *TheCall)
OpenCL C v2.0, s6.13.17.6 - Check the argument to the get_kernel_work_group_size and get_kernel_prefe...
bool checkBuiltinEnqueueKernel(CallExpr *TheCall)
OpenCL C v2.0, s6.13.17 - Enqueue kernel function contains four different overload formats specified ...
bool checkBuiltinCommitRWPipe(CallExpr *Call)
bool checkBuiltinPipePackets(CallExpr *Call)
void handleNoSVMAttr(Decl *D, const ParsedAttr &AL)
bool checkSubgroupExt(CallExpr *Call)
void handleAccessAttr(Decl *D, const ParsedAttr &AL)
bool checkBuiltinToAddr(unsigned BuiltinID, CallExpr *Call)
bool checkBuiltinRWPipe(CallExpr *Call)
bool checkBuiltinReserveRWPipe(CallExpr *Call)
Sema - This implements semantic analysis and AST building for C.
OpenCLOptions & getOpenCLOptions()
void CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, bool *ICContext=nullptr, bool IsListInit=false)
bool checkArgCount(CallExpr *Call, unsigned DesiredArgCount)
Checks that a call expression's argument count is the desired number.
Encodes a location in the source.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
The base class of the type hierarchy.
bool isBlockPointerType() const
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
QualType getCanonicalTypeInternal() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * getAs() const
Member-template getAs<specific type>'.
unsigned llvm::PointerUnion< const Decl *, const Expr * > DeclTy
The JSON file list parser is used to communicate input to InstallAPI.
static bool checkBlockArgs(Sema &S, Expr *BlockArg)
OpenCL C v2.0, s6.13.17.2 - Checks that the block parameters are all local void*, which is a requirem...
static bool checkOpenCLEnqueueIntType(Sema &S, Expr *E, const QualType &IntT)
Diagnose integer type and any valid implicit conversion to it.
static bool checkPipeArg(Sema &S, CallExpr *Call)
Returns true if pipe element type is different from the pointer.
static bool isBlockPointer(Expr *Arg)
static bool checkOpenCLEnqueueVariadicArgs(Sema &S, CallExpr *TheCall, Expr *BlockArg, unsigned NumNonVarArgs)
OpenCL v2.0, s6.13.17.1 - Check that sizes are provided for all 'local void*' parameter of passed blo...
static bool checkOpenCLEnqueueLocalSizeArgs(Sema &S, CallExpr *TheCall, unsigned Start, unsigned End)
static bool checkPipePacketType(Sema &S, CallExpr *Call, unsigned Idx)
Returns true if pipe element type is different from the pointer.
static OpenCLAccessAttr * getOpenCLArgAccess(const Decl *D)
Returns OpenCL access qual.