26 if (
getLangOpts().getOpenCLCompatibleVersion() < 200)
27 Diag(AL.
getLoc(), diag::err_attribute_requires_opencl_version)
30 Diag(AL.
getLoc(), diag::warn_opencl_attr_deprecated_ignored)
39 if (D->
hasAttr<OpenCLAccessAttr>()) {
40 if (D->
getAttr<OpenCLAccessAttr>()->getSemanticSpelling() ==
42 Diag(AL.
getLoc(), diag::warn_duplicate_declspec)
45 Diag(AL.
getLoc(), diag::err_opencl_multiple_access_qualifiers)
61 if (
const auto *PDecl = dyn_cast<ParmVarDecl>(D)) {
62 const Type *DeclTy = PDecl->getType().getCanonicalType().getTypePtr();
64 bool ReadWriteImagesUnsupported =
66 (
getLangOpts().getOpenCLCompatibleVersion() == 300 &&
67 !
SemaRef.getOpenCLOptions().isSupported(
69 if (ReadWriteImagesUnsupported || DeclTy->isPipeType()) {
70 Diag(AL.
getLoc(), diag::err_opencl_invalid_read_write)
71 << AL << PDecl->getType() << DeclTy->isImageType();
84 if (!
SemaRef.checkUInt32Argument(AL, E, SGSize))
87 Diag(AL.
getLoc(), diag::err_attribute_argument_is_zero)
92 OpenCLIntelReqdSubGroupSizeAttr *Existing =
93 D->
getAttr<OpenCLIntelReqdSubGroupSizeAttr>();
94 if (Existing && Existing->getSubGroupSize() != SGSize)
95 Diag(AL.
getLoc(), diag::warn_duplicate_attribute) << AL;
98 OpenCLIntelReqdSubGroupSizeAttr(
getASTContext(), AL, SGSize));
112 unsigned ArgCounter = 0;
113 bool IllegalParams =
false;
117 I != E; ++I, ++ArgCounter) {
118 if (!(*I)->isPointerType() || !(*I)->getPointeeType()->isVoidType() ||
119 (*I)->getPointeeType().getQualifiers().getAddressSpace() !=
132 diag::err_opencl_enqueue_kernel_blocks_non_local_void_args);
133 IllegalParams =
true;
137 return IllegalParams;
144 if (!
SemaRef.getOpenCLOptions().isSupported(
"cl_khr_subgroups",
146 !
SemaRef.getOpenCLOptions().isSupported(
"__opencl_c_subgroups",
148 Diag(
Call->getBeginLoc(), diag::err_opencl_requires_extension)
149 << 1 <<
Call->getDirectCallee()
150 <<
"cl_khr_subgroups or __opencl_c_subgroups";
157 if (
SemaRef.checkArgCount(TheCall, 2))
166 Diag(NDRangeArg->
getBeginLoc(), diag::err_opencl_builtin_expected_type)
181 if (
SemaRef.checkArgCount(TheCall, 1))
199 diag::err_opencl_enqueue_kernel_invalid_local_size_type);
209 unsigned Start,
unsigned End) {
210 bool IllegalParams =
false;
211 for (
unsigned I = Start; I <= End; ++I)
214 return IllegalParams;
221 unsigned NumNonVarArgs) {
224 unsigned NumBlockParams =
226 unsigned TotalNumArgs = TheCall->
getNumArgs();
230 if (TotalNumArgs != NumBlockParams + NumNonVarArgs) {
232 diag::err_opencl_enqueue_kernel_local_size_args);
246 Diag(TheCall->
getBeginLoc(), diag::err_typecheck_call_too_few_args_at_least)
247 << 0 << 4 << NumArgs << 0;
259 diag::err_opencl_builtin_expected_type)
267 diag::err_opencl_builtin_expected_type)
268 << TheCall->
getDirectCallee() <<
"'kernel_enqueue_flags_t' (i.e. uint)";
275 diag::err_opencl_builtin_expected_type)
294 Diag(Arg3->
getBeginLoc(), diag::err_opencl_enqueue_kernel_blocks_no_args);
318 diag::err_opencl_builtin_expected_type)
331 diag::err_opencl_builtin_expected_type)
333 << Context.getPointerType(Context.OCLClkEventTy);
343 diag::err_opencl_builtin_expected_type)
345 << Context.getPointerType(Context.OCLClkEventTy);
356 Diag(TheCall->
getBeginLoc(), diag::err_opencl_enqueue_kernel_incorrect_args);
362 return D->
getAttr<OpenCLAccessAttr>();
370 S.
Diag(
Call->getBeginLoc(), diag::err_opencl_builtin_pipe_first_arg)
374 OpenCLAccessAttr *AccessQual =
380 switch (
Call->getDirectCallee()->getBuiltinID()) {
381 case Builtin::BIread_pipe:
382 case Builtin::BIreserve_read_pipe:
383 case Builtin::BIcommit_read_pipe:
384 case Builtin::BIwork_group_reserve_read_pipe:
385 case Builtin::BIsub_group_reserve_read_pipe:
386 case Builtin::BIwork_group_commit_read_pipe:
387 case Builtin::BIsub_group_commit_read_pipe:
388 if (!(!AccessQual || AccessQual->isReadOnly())) {
390 diag::err_opencl_builtin_pipe_invalid_access_modifier)
395 case Builtin::BIwrite_pipe:
396 case Builtin::BIreserve_write_pipe:
397 case Builtin::BIcommit_write_pipe:
398 case Builtin::BIwork_group_reserve_write_pipe:
399 case Builtin::BIsub_group_reserve_write_pipe:
400 case Builtin::BIwork_group_commit_write_pipe:
401 case Builtin::BIsub_group_commit_write_pipe:
402 if (!(AccessQual && AccessQual->isWriteOnly())) {
404 diag::err_opencl_builtin_pipe_invalid_access_modifier)
418 const Expr *ArgIdx =
Call->getArg(Idx);
427 S.
Diag(
Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg)
438 switch (
Call->getNumArgs()) {
455 if (!
Call->getArg(1)->getType()->isReserveIDT()) {
456 Diag(
Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg)
458 <<
Call->getArg(1)->getType() <<
Call->getArg(1)->getSourceRange();
466 Diag(
Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg)
477 Diag(
Call->getBeginLoc(), diag::err_opencl_builtin_pipe_arg_num)
478 <<
Call->getDirectCallee() <<
Call->getSourceRange();
493 if (!
Call->getArg(1)->getType()->isIntegerType() &&
494 !
Call->getArg(1)->getType()->isUnsignedIntegerType()) {
495 Diag(
Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg)
497 <<
Call->getArg(1)->getType() <<
Call->getArg(1)->getSourceRange();
517 if (!
Call->getArg(1)->getType()->isReserveIDT()) {
518 Diag(
Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg)
520 <<
Call->getArg(1)->getType() <<
Call->getArg(1)->getSourceRange();
531 if (!
Call->getArg(0)->getType()->isPipeType()) {
532 Diag(
Call->getBeginLoc(), diag::err_opencl_builtin_pipe_first_arg)
533 <<
Call->getDirectCallee() <<
Call->getArg(0)->getSourceRange();
544 auto RT =
Call->getArg(0)->getType();
545 if (!RT->isPointerType() ||
547 Diag(
Call->getArg(0)->getBeginLoc(),
548 diag::err_opencl_builtin_to_addr_invalid_arg)
549 <<
Call->getArg(0) <<
Call->getDirectCallee() <<
Call->getSourceRange();
554 Diag(
Call->getArg(0)->getBeginLoc(),
555 diag::warn_opencl_generic_address_space_arg)
556 <<
Call->getDirectCallee()->getNameInfo().getAsString()
557 <<
Call->getArg(0)->getSourceRange();
560 RT = RT->getPointeeType();
561 auto Qual = RT.getQualifiers();
563 case Builtin::BIto_global:
566 case Builtin::BIto_local:
569 case Builtin::BIto_private:
573 llvm_unreachable(
"Invalid builtin function");
576 getASTContext().getQualifiedType(RT.getUnqualifiedType(), Qual)));
585 StringRef Name = II->
getName();
586 if (Name !=
"read_imagei" && Name !=
"read_imageui")
596 Expr *IntExpr =
nullptr;
599 if (
auto *DRE = dyn_cast<DeclRefExpr>(Inner)) {
600 if (
auto *Var = dyn_cast<VarDecl>(DRE->getDecl())) {
601 if (
const Expr *
Init = Var->getAnyInitializer()) {
603 if (
Init->getType()->isIntegerType())
618 uint64_t SamplerValue = EVResult.
Val.
getInt().getLimitedValue();
620 constexpr unsigned FilterModeMask = 0x30u;
621 constexpr unsigned FilterModeLinear = 0x20u;
622 if ((SamplerValue & FilterModeMask) == FilterModeLinear)
623 Diag(SamplerArg->
getExprLoc(), diag::warn_sampler_argument_invalid_filter)
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 ...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
CanQualType UnsignedIntTy
CanQualType OCLReserveIDTy
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
SourceRange getRange() const
SourceLocation getLoc() const
const IdentifierInfo * getAttrName() 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]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Decl - This represents one declaration (or definition), e.g.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
bool isInvalidDecl() const
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
SourceLocation getBeginLoc() const LLVM_READONLY
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
@ 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.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
One of these records is kept for each identifier that is lexed.
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.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
ParsedAttr - Represents a syntactic attribute.
unsigned getSemanticSpelling() const
If the parsed attribute has a semantic equivalent, and it would have a semantic Spelling enumeration ...
Expr * getArgAsExpr(unsigned Arg) const
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)
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
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)
void handleSubGroupSize(Decl *D, const ParsedAttr &AL)
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)
void checkBuiltinReadImage(FunctionDecl *FDecl, CallExpr *Call)
Sema - This implements semantic analysis and AST building for C.
void CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, bool *ICContext=nullptr, bool IsListInit=false)
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>'.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
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 OpenCLAccessAttr * getOpenCLArgAccess(const Decl *D)
Returns OpenCL access qual.
U cast(CodeGen::Address addr)
static bool checkPipePacketType(Sema &S, CallExpr *Call, unsigned Idx)
Returns true if pipe element type is different from the pointer.
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.