clang: lib/Sema/SemaOpenCL.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
19
22
24 if (getLangOpts().getOpenCLCompatibleVersion() < 200)
25 Diag(AL.getLoc(), diag::err_attribute_requires_opencl_version)
26 << AL << "2.0" << 1;
27 else
28 Diag(AL.getLoc(), diag::warn_opencl_attr_deprecated_ignored)
30}
31
34 return;
35
36
37 if (D->hasAttr()) {
38 if (D->getAttr()->getSemanticSpelling() ==
40 Diag(AL.getLoc(), diag::warn_duplicate_declspec)
42 } else {
43 Diag(AL.getLoc(), diag::err_opencl_multiple_access_qualifiers)
46 return;
47 }
48 }
49
50
51
52
53
54
55
56
57
58
59 if (const auto *PDecl = dyn_cast(D)) {
60 const Type *DeclTy = PDecl->getType().getCanonicalType().getTypePtr();
62 bool ReadWriteImagesUnsupported =
64 (getLangOpts().getOpenCLCompatibleVersion() == 300 &&
65 .getOpenCLOptions().isSupported(
66 "__opencl_c_read_write_images", getLangOpts()));
67 if (ReadWriteImagesUnsupported || DeclTy->isPipeType()) {
68 Diag(AL.getLoc(), diag::err_opencl_invalid_read_write)
69 << AL << PDecl->getType() << DeclTy->isImageType();
71 return;
72 }
73 }
74 }
75
77}
78
80 uint32_t SGSize;
82 if (.checkUInt32Argument(AL, E, SGSize))
83 return;
84 if (SGSize == 0) {
85 Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
87 return;
88 }
89
90 OpenCLIntelReqdSubGroupSizeAttr *Existing =
91 D->getAttr();
92 if (Existing && Existing->getSubGroupSize() != SGSize)
93 Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
94
96 OpenCLIntelReqdSubGroupSizeAttr(getASTContext(), AL, SGSize));
97}
98
102
103
104
110 unsigned ArgCounter = 0;
111 bool IllegalParams = false;
112
113
115 I != E; ++I, ++ArgCounter) {
116 if (!(*I)->isPointerType() || !(*I)->getPointeeType()->isVoidType() ||
117 (*I)->getPointeeType().getQualifiers().getAddressSpace() !=
119
120
121
128 }
129 S.Diag(ErrorLoc,
130 diag::err_opencl_enqueue_kernel_blocks_non_local_void_args);
131 IllegalParams = true;
132 }
133 }
134
135 return IllegalParams;
136}
137
139
140
141
142 if (.getOpenCLOptions().isSupported("cl_khr_subgroups",
144 .getOpenCLOptions().isSupported("__opencl_c_subgroups",
146 Diag(Call->getBeginLoc(), diag::err_opencl_requires_extension)
147 << 1 << Call->getDirectCallee()
148 << "cl_khr_subgroups or __opencl_c_subgroups";
149 return true;
150 }
151 return false;
152}
153
155 if (SemaRef.checkArgCount(TheCall, 2))
156 return true;
157
159 return true;
160
161
162 Expr *NDRangeArg = TheCall->getArg(0);
164 Diag(NDRangeArg->getBeginLoc(), diag::err_opencl_builtin_expected_type)
166 return true;
167 }
168
171 Diag(BlockArg->getBeginLoc(), diag::err_opencl_builtin_expected_type)
173 return true;
174 }
176}
177
179 if (SemaRef.checkArgCount(TheCall, 1))
180 return true;
181
184 Diag(BlockArg->getBeginLoc(), diag::err_opencl_builtin_expected_type)
186 return true;
187 }
189}
190
191
193
194
197 diag::err_opencl_enqueue_kernel_invalid_local_size_type);
198 return true;
199 }
200
201
203 return false;
204}
205
207 unsigned Start, unsigned End) {
208 bool IllegalParams = false;
209 for (unsigned I = Start; I <= End; ++I)
212 return IllegalParams;
213}
214
215
216
218 Expr *BlockArg,
219 unsigned NumNonVarArgs) {
222 unsigned NumBlockParams =
224 unsigned TotalNumArgs = TheCall->getNumArgs();
225
226
227
228 if (TotalNumArgs != NumBlockParams + NumNonVarArgs) {
230 diag::err_opencl_enqueue_kernel_local_size_args);
231 return true;
232 }
233
234
236 TotalNumArgs - 1);
237}
238
241 unsigned NumArgs = TheCall->getNumArgs();
242
243 if (NumArgs < 4) {
244 Diag(TheCall->getBeginLoc(), diag::err_typecheck_call_too_few_args_at_least)
245 << 0 << 4 << NumArgs << 0;
246 return true;
247 }
248
253
254
257 diag::err_opencl_builtin_expected_type)
259 return true;
260 }
261
262
265 diag::err_opencl_builtin_expected_type)
266 << TheCall->getDirectCallee() << "'kernel_enqueue_flags_t' (i.e. uint)";
267 return true;
268 }
269
270
273 diag::err_opencl_builtin_expected_type)
275 return true;
276 }
277
278
279
280 if (NumArgs == 4) {
281
283 Diag(Arg3->getBeginLoc(), diag::err_opencl_builtin_expected_type)
285 return true;
286 }
287
291 0) {
292 Diag(Arg3->getBeginLoc(), diag::err_opencl_enqueue_kernel_blocks_no_args);
293 return true;
294 }
295 return false;
296 }
297
301
302 if (NumArgs >= 7) {
303
306 Diag(Arg6->getBeginLoc(), diag::err_opencl_builtin_expected_type)
308 return true;
309 }
311 return true;
312
313
316 diag::err_opencl_builtin_expected_type)
318 return true;
319 }
320
323
324
329 diag::err_opencl_builtin_expected_type)
331 << Context.getPointerType(Context.OCLClkEventTy);
332 return true;
333 }
334
335
341 diag::err_opencl_builtin_expected_type)
343 << Context.getPointerType(Context.OCLClkEventTy);
344 return true;
345 }
346
347 if (NumArgs == 7)
348 return false;
349
351 }
352
353
354 Diag(TheCall->getBeginLoc(), diag::err_opencl_enqueue_kernel_incorrect_args);
355 return true;
356}
357
358
360 return D->getAttr();
361}
362
363
365 const Expr *Arg0 = Call->getArg(0);
366
368 S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_first_arg)
370 return true;
371 }
372 OpenCLAccessAttr *AccessQual =
374
375
376
377
378 switch (Call->getDirectCallee()->getBuiltinID()) {
379 case Builtin::BIread_pipe:
380 case Builtin::BIreserve_read_pipe:
381 case Builtin::BIcommit_read_pipe:
382 case Builtin::BIwork_group_reserve_read_pipe:
383 case Builtin::BIsub_group_reserve_read_pipe:
384 case Builtin::BIwork_group_commit_read_pipe:
385 case Builtin::BIsub_group_commit_read_pipe:
386 if (!(!AccessQual || AccessQual->isReadOnly())) {
388 diag::err_opencl_builtin_pipe_invalid_access_modifier)
390 return true;
391 }
392 break;
393 case Builtin::BIwrite_pipe:
394 case Builtin::BIreserve_write_pipe:
395 case Builtin::BIcommit_write_pipe:
396 case Builtin::BIwork_group_reserve_write_pipe:
397 case Builtin::BIsub_group_reserve_write_pipe:
398 case Builtin::BIwork_group_commit_write_pipe:
399 case Builtin::BIsub_group_commit_write_pipe:
400 if (!(AccessQual && AccessQual->isWriteOnly())) {
402 diag::err_opencl_builtin_pipe_invalid_access_modifier)
404 return true;
405 }
406 break;
407 default:
408 break;
409 }
410 return false;
411}
412
413
415 const Expr *Arg0 = Call->getArg(0);
416 const Expr *ArgIdx = Call->getArg(Idx);
420
421
422 if (!ArgTy ||
425 S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg)
428 return true;
429 }
430 return false;
431}
432
434
435
436 switch (Call->getNumArgs()) {
437 case 2:
439 return true;
440
441
442
444 return true;
445 break;
446
447 case 4: {
449 return true;
450
451
452
453 if (->getArg(1)->getType()->isReserveIDT()) {
454 Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg)
456 << Call->getArg(1)->getType() << Call->getArg(1)->getSourceRange();
457 return true;
458 }
459
460
461 const Expr *Arg2 = Call->getArg(2);
464 Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg)
467 return true;
468 }
469
470
472 return true;
473 } break;
474 default:
475 Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_arg_num)
476 << Call->getDirectCallee() << Call->getSourceRange();
477 return true;
478 }
479
480 return false;
481}
482
485 return true;
486
488 return true;
489
490
491 if (->getArg(1)->getType()->isIntegerType() &&
492 ->getArg(1)->getType()->isUnsignedIntegerType()) {
493 Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg)
495 << Call->getArg(1)->getType() << Call->getArg(1)->getSourceRange();
496 return true;
497 }
498
499
500
501
503
504 return false;
505}
506
509 return true;
510
512 return true;
513
514
515 if (->getArg(1)->getType()->isReserveIDT()) {
516 Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg)
518 << Call->getArg(1)->getType() << Call->getArg(1)->getSourceRange();
519 return true;
520 }
521
522 return false;
523}
524
527 return true;
528
529 if (->getArg(0)->getType()->isPipeType()) {
530 Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_first_arg)
531 << Call->getDirectCallee() << Call->getArg(0)->getSourceRange();
532 return true;
533 }
534
535 return false;
536}
537
540 return true;
541
542 auto RT = Call->getArg(0)->getType();
543 if (!RT->isPointerType() ||
545 Diag(Call->getArg(0)->getBeginLoc(),
546 diag::err_opencl_builtin_to_addr_invalid_arg)
547 << Call->getArg(0) << Call->getDirectCallee() << Call->getSourceRange();
548 return true;
549 }
550
552 Diag(Call->getArg(0)->getBeginLoc(),
553 diag::warn_opencl_generic_address_space_arg)
554 << Call->getDirectCallee()->getNameInfo().getAsString()
555 << Call->getArg(0)->getSourceRange();
556 }
557
558 RT = RT->getPointeeType();
559 auto Qual = RT.getQualifiers();
560 switch (BuiltinID) {
561 case Builtin::BIto_global:
563 break;
564 case Builtin::BIto_local:
566 break;
567 case Builtin::BIto_private:
569 break;
570 default:
571 llvm_unreachable("Invalid builtin function");
572 }
574 getASTContext().getQualifiedType(RT.getUnqualifiedType(), Qual)));
575
576 return false;
577}
578
579}
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.
@ 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.
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)
Definition SemaOpenCL.cpp:154
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...
Definition SemaOpenCL.cpp:178
bool checkBuiltinEnqueueKernel(CallExpr *TheCall)
OpenCL C v2.0, s6.13.17 - Enqueue kernel function contains four different overload formats specified ...
Definition SemaOpenCL.cpp:239
bool checkBuiltinCommitRWPipe(CallExpr *Call)
Definition SemaOpenCL.cpp:507
void handleSubGroupSize(Decl *D, const ParsedAttr &AL)
Definition SemaOpenCL.cpp:79
bool checkBuiltinPipePackets(CallExpr *Call)
Definition SemaOpenCL.cpp:525
void handleNoSVMAttr(Decl *D, const ParsedAttr &AL)
Definition SemaOpenCL.cpp:23
bool checkSubgroupExt(CallExpr *Call)
Definition SemaOpenCL.cpp:138
void handleAccessAttr(Decl *D, const ParsedAttr &AL)
Definition SemaOpenCL.cpp:32
bool checkBuiltinToAddr(unsigned BuiltinID, CallExpr *Call)
Definition SemaOpenCL.cpp:538
bool checkBuiltinRWPipe(CallExpr *Call)
Definition SemaOpenCL.cpp:433
bool checkBuiltinReserveRWPipe(CallExpr *Call)
Definition SemaOpenCL.cpp:483
SemaOpenCL(Sema &S)
Definition SemaOpenCL.cpp:21
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.
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'.
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...
Definition SemaOpenCL.cpp:105
static bool checkOpenCLEnqueueIntType(Sema &S, Expr *E, const QualType &IntT)
Diagnose integer type and any valid implicit conversion to it.
Definition SemaOpenCL.cpp:192
static bool checkPipeArg(Sema &S, CallExpr *Call)
Returns true if pipe element type is different from the pointer.
Definition SemaOpenCL.cpp:364
static bool isBlockPointer(Expr *Arg)
Definition SemaOpenCL.cpp:99
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...
Definition SemaOpenCL.cpp:217
static bool checkOpenCLEnqueueLocalSizeArgs(Sema &S, CallExpr *TheCall, unsigned Start, unsigned End)
Definition SemaOpenCL.cpp:206
static OpenCLAccessAttr * getOpenCLArgAccess(const Decl *D)
Returns OpenCL access qual.
Definition SemaOpenCL.cpp:359
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.
Definition SemaOpenCL.cpp:414