clang 22.0.0git
SemaAMDGPU.cpp
Go to the documentation of this file.
1//===------ SemaAMDGPU.cpp ------- AMDGPU target-specific routines --------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements semantic analysis functions specific to AMDGPU.
10//
11//===----------------------------------------------------------------------===//
12
17#include "clang/Sema/Sema.h"
18#include "llvm/Support/AMDGPUAddrSpace.h"
19#include "llvm/Support/AtomicOrdering.h"
20#include <cstdint>
21
22namespace clang {
23
25
27 CallExpr *TheCall) {
28 // position of memory order and scope arguments in the builtin
29 unsigned OrderIndex, ScopeIndex;
30
31 const auto *FD = SemaRef.getCurFunctionDecl(/*AllowLambda=*/true);
32 assert(FD && "AMDGPU builtins should not be used outside of a function");
33 llvm::StringMap<bool> CallerFeatureMap;
34 getASTContext().getFunctionFeatureMap(CallerFeatureMap, FD);
35 bool HasGFX950Insts =
36 Builtin::evaluateRequiredTargetFeatures("gfx950-insts", CallerFeatureMap);
37
38 switch (BuiltinID) {
39 case AMDGPU::BI__builtin_amdgcn_raw_ptr_buffer_load_lds:
40 case AMDGPU::BI__builtin_amdgcn_struct_ptr_buffer_load_lds:
41 case AMDGPU::BI__builtin_amdgcn_load_to_lds:
42 case AMDGPU::BI__builtin_amdgcn_global_load_lds: {
43 constexpr const int SizeIdx = 2;
44 llvm::APSInt Size;
45 Expr *ArgExpr = TheCall->getArg(SizeIdx);
46 [[maybe_unused]] ExprResult R =
47 SemaRef.VerifyIntegerConstantExpression(ArgExpr, &Size);
48 assert(!R.isInvalid());
49 switch (Size.getSExtValue()) {
50 case 1:
51 case 2:
52 case 4:
53 return false;
54 case 12:
55 case 16: {
56 if (HasGFX950Insts)
57 return false;
58 [[fallthrough]];
59 }
60 default:
61 Diag(ArgExpr->getExprLoc(), diag::err_amdgcn_load_lds_size_invalid_value)
62 << ArgExpr->getSourceRange();
63 Diag(ArgExpr->getExprLoc(), diag::note_amdgcn_load_lds_size_valid_value)
64 << HasGFX950Insts << ArgExpr->getSourceRange();
65 return true;
66 }
67 }
68 case AMDGPU::BI__builtin_amdgcn_get_fpenv:
69 case AMDGPU::BI__builtin_amdgcn_set_fpenv:
70 return false;
71 case AMDGPU::BI__builtin_amdgcn_atomic_inc32:
72 case AMDGPU::BI__builtin_amdgcn_atomic_inc64:
73 case AMDGPU::BI__builtin_amdgcn_atomic_dec32:
74 case AMDGPU::BI__builtin_amdgcn_atomic_dec64:
75 OrderIndex = 2;
76 ScopeIndex = 3;
77 break;
78 case AMDGPU::BI__builtin_amdgcn_fence:
79 OrderIndex = 0;
80 ScopeIndex = 1;
81 break;
82 case AMDGPU::BI__builtin_amdgcn_mov_dpp:
83 return checkMovDPPFunctionCall(TheCall, 5, 1);
84 case AMDGPU::BI__builtin_amdgcn_mov_dpp8:
85 return checkMovDPPFunctionCall(TheCall, 2, 1);
86 case AMDGPU::BI__builtin_amdgcn_update_dpp:
87 return checkMovDPPFunctionCall(TheCall, 6, 2);
88 case AMDGPU::BI__builtin_amdgcn_cvt_scale_pk8_f16_fp8:
89 case AMDGPU::BI__builtin_amdgcn_cvt_scale_pk8_bf16_fp8:
90 case AMDGPU::BI__builtin_amdgcn_cvt_scale_pk8_f16_bf8:
91 case AMDGPU::BI__builtin_amdgcn_cvt_scale_pk8_bf16_bf8:
92 case AMDGPU::BI__builtin_amdgcn_cvt_scale_pk8_f16_fp4:
93 case AMDGPU::BI__builtin_amdgcn_cvt_scale_pk8_bf16_fp4:
94 case AMDGPU::BI__builtin_amdgcn_cvt_scale_pk8_f32_fp8:
95 case AMDGPU::BI__builtin_amdgcn_cvt_scale_pk8_f32_bf8:
96 case AMDGPU::BI__builtin_amdgcn_cvt_scale_pk8_f32_fp4:
97 case AMDGPU::BI__builtin_amdgcn_cvt_scale_pk16_f16_fp6:
98 case AMDGPU::BI__builtin_amdgcn_cvt_scale_pk16_bf16_fp6:
99 case AMDGPU::BI__builtin_amdgcn_cvt_scale_pk16_f16_bf6:
100 case AMDGPU::BI__builtin_amdgcn_cvt_scale_pk16_bf16_bf6:
101 case AMDGPU::BI__builtin_amdgcn_cvt_scale_pk16_f32_fp6:
102 case AMDGPU::BI__builtin_amdgcn_cvt_scale_pk16_f32_bf6:
103 return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 7);
104 case AMDGPU::BI__builtin_amdgcn_cooperative_atomic_load_32x4B:
105 case AMDGPU::BI__builtin_amdgcn_cooperative_atomic_load_16x8B:
106 case AMDGPU::BI__builtin_amdgcn_cooperative_atomic_load_8x16B:
107 return checkCoopAtomicFunctionCall(TheCall, /*IsStore=*/false);
108 case AMDGPU::BI__builtin_amdgcn_cooperative_atomic_store_32x4B:
109 case AMDGPU::BI__builtin_amdgcn_cooperative_atomic_store_16x8B:
110 case AMDGPU::BI__builtin_amdgcn_cooperative_atomic_store_8x16B:
111 return checkCoopAtomicFunctionCall(TheCall, /*IsStore=*/true);
112 default:
113 return false;
114 }
115
116 ExprResult Arg = TheCall->getArg(OrderIndex);
117 auto ArgExpr = Arg.get();
118 Expr::EvalResult ArgResult;
119
120 if (!ArgExpr->EvaluateAsInt(ArgResult, getASTContext()))
121 return Diag(ArgExpr->getExprLoc(), diag::err_typecheck_expect_int)
122 << ArgExpr->getType();
123 auto Ord = ArgResult.Val.getInt().getZExtValue();
124
125 // Check validity of memory ordering as per C11 / C++11's memody model.
126 // Only fence needs check. Atomic dec/inc allow all memory orders.
127 if (!llvm::isValidAtomicOrderingCABI(Ord))
128 return Diag(ArgExpr->getBeginLoc(),
129 diag::warn_atomic_op_has_invalid_memory_order)
130 << 0 << ArgExpr->getSourceRange();
131 switch (static_cast<llvm::AtomicOrderingCABI>(Ord)) {
132 case llvm::AtomicOrderingCABI::relaxed:
133 case llvm::AtomicOrderingCABI::consume:
134 if (BuiltinID == AMDGPU::BI__builtin_amdgcn_fence)
135 return Diag(ArgExpr->getBeginLoc(),
136 diag::warn_atomic_op_has_invalid_memory_order)
137 << 0 << ArgExpr->getSourceRange();
138 break;
139 case llvm::AtomicOrderingCABI::acquire:
140 case llvm::AtomicOrderingCABI::release:
141 case llvm::AtomicOrderingCABI::acq_rel:
142 case llvm::AtomicOrderingCABI::seq_cst:
143 break;
144 }
145
146 Arg = TheCall->getArg(ScopeIndex);
147 ArgExpr = Arg.get();
148 Expr::EvalResult ArgResult1;
149 // Check that sync scope is a constant literal
150 if (!ArgExpr->EvaluateAsConstantExpr(ArgResult1, getASTContext()))
151 return Diag(ArgExpr->getExprLoc(), diag::err_expr_not_string_literal)
152 << ArgExpr->getType();
153
154 return false;
155}
156
158 bool Fail = false;
159
160 // First argument is a global or generic pointer.
161 Expr *PtrArg = TheCall->getArg(0);
162 QualType PtrTy = PtrArg->getType()->getPointeeType();
163 unsigned AS = getASTContext().getTargetAddressSpace(PtrTy.getAddressSpace());
164 if (AS != llvm::AMDGPUAS::FLAT_ADDRESS &&
165 AS != llvm::AMDGPUAS::GLOBAL_ADDRESS) {
166 Fail = true;
167 Diag(TheCall->getBeginLoc(), diag::err_amdgcn_coop_atomic_invalid_as)
168 << PtrArg->getSourceRange();
169 }
170
171 // Check atomic ordering
172 Expr *AtomicOrdArg = TheCall->getArg(IsStore ? 2 : 1);
173 Expr::EvalResult AtomicOrdArgRes;
174 if (!AtomicOrdArg->EvaluateAsInt(AtomicOrdArgRes, getASTContext()))
175 llvm_unreachable("Intrinsic requires imm for atomic ordering argument!");
176 auto Ord =
177 llvm::AtomicOrderingCABI(AtomicOrdArgRes.Val.getInt().getZExtValue());
178
179 // Atomic ordering cannot be acq_rel in any case, acquire for stores or
180 // release for loads.
181 if (!llvm::isValidAtomicOrderingCABI((unsigned)Ord) ||
182 (Ord == llvm::AtomicOrderingCABI::acq_rel) ||
183 Ord == (IsStore ? llvm::AtomicOrderingCABI::acquire
184 : llvm::AtomicOrderingCABI::release)) {
185 return Diag(AtomicOrdArg->getBeginLoc(),
186 diag::warn_atomic_op_has_invalid_memory_order)
187 << 0 << AtomicOrdArg->getSourceRange();
188 }
189
190 // Last argument is a string literal
191 Expr *Arg = TheCall->getArg(TheCall->getNumArgs() - 1);
193 Fail = true;
194 Diag(TheCall->getBeginLoc(), diag::err_expr_not_string_literal)
195 << Arg->getSourceRange();
196 }
197
198 return Fail;
199}
200
201bool SemaAMDGPU::checkMovDPPFunctionCall(CallExpr *TheCall, unsigned NumArgs,
202 unsigned NumDataArgs) {
203 assert(NumDataArgs <= 2);
204 if (SemaRef.checkArgCountRange(TheCall, NumArgs, NumArgs))
205 return true;
206 Expr *Args[2];
207 QualType ArgTys[2];
208 for (unsigned I = 0; I != NumDataArgs; ++I) {
209 Args[I] = TheCall->getArg(I);
210 ArgTys[I] = Args[I]->getType();
211 // TODO: Vectors can also be supported.
212 if (!ArgTys[I]->isArithmeticType() || ArgTys[I]->isAnyComplexType()) {
213 SemaRef.Diag(Args[I]->getBeginLoc(),
214 diag::err_typecheck_cond_expect_int_float)
215 << ArgTys[I] << Args[I]->getSourceRange();
216 return true;
217 }
218 }
219 if (NumDataArgs < 2)
220 return false;
221
222 if (getASTContext().hasSameUnqualifiedType(ArgTys[0], ArgTys[1]))
223 return false;
224
225 if (((ArgTys[0]->isUnsignedIntegerType() &&
226 ArgTys[1]->isSignedIntegerType()) ||
227 (ArgTys[0]->isSignedIntegerType() &&
228 ArgTys[1]->isUnsignedIntegerType())) &&
229 getASTContext().getTypeSize(ArgTys[0]) ==
230 getASTContext().getTypeSize(ArgTys[1]))
231 return false;
232
233 SemaRef.Diag(Args[1]->getBeginLoc(),
234 diag::err_typecheck_call_different_arg_types)
235 << ArgTys[0] << ArgTys[1];
236 return true;
237}
238
239static bool
241 const AMDGPUFlatWorkGroupSizeAttr &Attr) {
242 // Accept template arguments for now as they depend on something else.
243 // We'll get to check them when they eventually get instantiated.
244 if (MinExpr->isValueDependent() || MaxExpr->isValueDependent())
245 return false;
246
247 uint32_t Min = 0;
248 if (!S.checkUInt32Argument(Attr, MinExpr, Min, 0))
249 return true;
250
251 uint32_t Max = 0;
252 if (!S.checkUInt32Argument(Attr, MaxExpr, Max, 1))
253 return true;
254
255 if (Min == 0 && Max != 0) {
256 S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid)
257 << &Attr << 0;
258 return true;
259 }
260 if (Min > Max) {
261 S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid)
262 << &Attr << 1;
263 return true;
264 }
265
266 return false;
267}
268
269AMDGPUFlatWorkGroupSizeAttr *
271 Expr *MinExpr, Expr *MaxExpr) {
272 ASTContext &Context = getASTContext();
273 AMDGPUFlatWorkGroupSizeAttr TmpAttr(Context, CI, MinExpr, MaxExpr);
274
275 if (checkAMDGPUFlatWorkGroupSizeArguments(SemaRef, MinExpr, MaxExpr, TmpAttr))
276 return nullptr;
277 return ::new (Context)
278 AMDGPUFlatWorkGroupSizeAttr(Context, CI, MinExpr, MaxExpr);
279}
280
282 const AttributeCommonInfo &CI,
283 Expr *MinExpr, Expr *MaxExpr) {
284 if (auto *Attr = CreateAMDGPUFlatWorkGroupSizeAttr(CI, MinExpr, MaxExpr))
285 D->addAttr(Attr);
286}
287
289 const ParsedAttr &AL) {
290 Expr *MinExpr = AL.getArgAsExpr(0);
291 Expr *MaxExpr = AL.getArgAsExpr(1);
292
293 addAMDGPUFlatWorkGroupSizeAttr(D, AL, MinExpr, MaxExpr);
294}
295
296static bool checkAMDGPUWavesPerEUArguments(Sema &S, Expr *MinExpr,
297 Expr *MaxExpr,
298 const AMDGPUWavesPerEUAttr &Attr) {
299 if (S.DiagnoseUnexpandedParameterPack(MinExpr) ||
300 (MaxExpr && S.DiagnoseUnexpandedParameterPack(MaxExpr)))
301 return true;
302
303 // Accept template arguments for now as they depend on something else.
304 // We'll get to check them when they eventually get instantiated.
305 if (MinExpr->isValueDependent() || (MaxExpr && MaxExpr->isValueDependent()))
306 return false;
307
308 uint32_t Min = 0;
309 if (!S.checkUInt32Argument(Attr, MinExpr, Min, 0))
310 return true;
311
312 uint32_t Max = 0;
313 if (MaxExpr && !S.checkUInt32Argument(Attr, MaxExpr, Max, 1))
314 return true;
315
316 if (Min == 0 && Max != 0) {
317 S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid)
318 << &Attr << 0;
319 return true;
320 }
321 if (Max != 0 && Min > Max) {
322 S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid)
323 << &Attr << 1;
324 return true;
325 }
326
327 return false;
328}
329
330AMDGPUWavesPerEUAttr *
332 Expr *MinExpr, Expr *MaxExpr) {
333 ASTContext &Context = getASTContext();
334 AMDGPUWavesPerEUAttr TmpAttr(Context, CI, MinExpr, MaxExpr);
335
336 if (checkAMDGPUWavesPerEUArguments(SemaRef, MinExpr, MaxExpr, TmpAttr))
337 return nullptr;
338
339 return ::new (Context) AMDGPUWavesPerEUAttr(Context, CI, MinExpr, MaxExpr);
340}
341
343 Expr *MinExpr, Expr *MaxExpr) {
344 if (auto *Attr = CreateAMDGPUWavesPerEUAttr(CI, MinExpr, MaxExpr))
345 D->addAttr(Attr);
346}
347
350 return;
351
352 Expr *MinExpr = AL.getArgAsExpr(0);
353 Expr *MaxExpr = (AL.getNumArgs() > 1) ? AL.getArgAsExpr(1) : nullptr;
354
355 addAMDGPUWavesPerEUAttr(D, AL, MinExpr, MaxExpr);
356}
357
359 uint32_t NumSGPR = 0;
360 Expr *NumSGPRExpr = AL.getArgAsExpr(0);
361 if (!SemaRef.checkUInt32Argument(AL, NumSGPRExpr, NumSGPR))
362 return;
363
364 D->addAttr(::new (getASTContext())
365 AMDGPUNumSGPRAttr(getASTContext(), AL, NumSGPR));
366}
367
369 uint32_t NumVGPR = 0;
370 Expr *NumVGPRExpr = AL.getArgAsExpr(0);
371 if (!SemaRef.checkUInt32Argument(AL, NumVGPRExpr, NumVGPR))
372 return;
373
374 D->addAttr(::new (getASTContext())
375 AMDGPUNumVGPRAttr(getASTContext(), AL, NumVGPR));
376}
377
378static bool
380 Expr *ZExpr,
381 const AMDGPUMaxNumWorkGroupsAttr &Attr) {
382 if (S.DiagnoseUnexpandedParameterPack(XExpr) ||
383 (YExpr && S.DiagnoseUnexpandedParameterPack(YExpr)) ||
384 (ZExpr && S.DiagnoseUnexpandedParameterPack(ZExpr)))
385 return true;
386
387 // Accept template arguments for now as they depend on something else.
388 // We'll get to check them when they eventually get instantiated.
389 if (XExpr->isValueDependent() || (YExpr && YExpr->isValueDependent()) ||
390 (ZExpr && ZExpr->isValueDependent()))
391 return false;
392
393 uint32_t NumWG = 0;
394 Expr *Exprs[3] = {XExpr, YExpr, ZExpr};
395 for (int i = 0; i < 3; i++) {
396 if (Exprs[i]) {
397 if (!S.checkUInt32Argument(Attr, Exprs[i], NumWG, i,
398 /*StrictlyUnsigned=*/true))
399 return true;
400 if (NumWG == 0) {
401 S.Diag(Attr.getLoc(), diag::err_attribute_argument_is_zero)
402 << &Attr << Exprs[i]->getSourceRange();
403 return true;
404 }
405 }
406 }
407
408 return false;
409}
410
412 const AttributeCommonInfo &CI, Expr *XExpr, Expr *YExpr, Expr *ZExpr) {
413 ASTContext &Context = getASTContext();
414 AMDGPUMaxNumWorkGroupsAttr TmpAttr(Context, CI, XExpr, YExpr, ZExpr);
415
416 if (checkAMDGPUMaxNumWorkGroupsArguments(SemaRef, XExpr, YExpr, ZExpr,
417 TmpAttr))
418 return nullptr;
419
420 return ::new (Context)
421 AMDGPUMaxNumWorkGroupsAttr(Context, CI, XExpr, YExpr, ZExpr);
422}
423
425 const AttributeCommonInfo &CI,
426 Expr *XExpr, Expr *YExpr,
427 Expr *ZExpr) {
428 if (auto *Attr = CreateAMDGPUMaxNumWorkGroupsAttr(CI, XExpr, YExpr, ZExpr))
429 D->addAttr(Attr);
430}
431
433 const ParsedAttr &AL) {
434 Expr *YExpr = (AL.getNumArgs() > 1) ? AL.getArgAsExpr(1) : nullptr;
435 Expr *ZExpr = (AL.getNumArgs() > 2) ? AL.getArgAsExpr(2) : nullptr;
436 addAMDGPUMaxNumWorkGroupsAttr(D, AL, AL.getArgAsExpr(0), YExpr, ZExpr);
437}
438
439} // namespace clang
This file declares semantic analysis functions specific to AMDGPU.
Enumerates target-specific builtins in their own namespaces within namespace clang.
APSInt & getInt()
Definition APValue.h:489
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:188
void getFunctionFeatureMap(llvm::StringMap< bool > &FeatureMap, const FunctionDecl *) const
unsigned getTargetAddressSpace(LangAS AS) const
PtrTy get() const
Definition Ownership.h:171
bool isInvalid() const
Definition Ownership.h:167
Attr - This represents one attribute.
Definition Attr.h:44
SourceLocation getLocation() const
Definition Attr.h:97
SourceLocation getLoc() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2879
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition Expr.h:3083
SourceLocation getBeginLoc() const
Definition Expr.h:3213
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition Expr.h:3070
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
void addAttr(Attr *A)
This represents one expression.
Definition Expr.h:112
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,...
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition Expr.h:177
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition Expr.cpp:3073
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition Expr.cpp:273
QualType getType() const
Definition Expr.h:144
ParsedAttr - Represents a syntactic attribute.
Definition ParsedAttr.h:119
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this attribute.
Definition ParsedAttr.h:371
Expr * getArgAsExpr(unsigned Arg) const
Definition ParsedAttr.h:383
bool checkAtLeastNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has at least as many args as Num.
bool checkAtMostNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has at most as many args as Num.
A (possibly-)qualified type.
Definition TypeBase.h:937
void handleAMDGPUMaxNumWorkGroupsAttr(Decl *D, const ParsedAttr &AL)
void addAMDGPUFlatWorkGroupSizeAttr(Decl *D, const AttributeCommonInfo &CI, Expr *Min, Expr *Max)
addAMDGPUFlatWorkGroupSizeAttr - Adds an amdgpu_flat_work_group_size attribute to a particular declar...
bool checkCoopAtomicFunctionCall(CallExpr *TheCall, bool IsStore)
void handleAMDGPUFlatWorkGroupSizeAttr(Decl *D, const ParsedAttr &AL)
void handleAMDGPUNumSGPRAttr(Decl *D, const ParsedAttr &AL)
AMDGPUMaxNumWorkGroupsAttr * CreateAMDGPUMaxNumWorkGroupsAttr(const AttributeCommonInfo &CI, Expr *XExpr, Expr *YExpr, Expr *ZExpr)
Create an AMDGPUMaxNumWorkGroupsAttr attribute.
AMDGPUWavesPerEUAttr * CreateAMDGPUWavesPerEUAttr(const AttributeCommonInfo &CI, Expr *Min, Expr *Max)
Create an AMDGPUWavesPerEUAttr attribute.
void handleAMDGPUNumVGPRAttr(Decl *D, const ParsedAttr &AL)
AMDGPUFlatWorkGroupSizeAttr * CreateAMDGPUFlatWorkGroupSizeAttr(const AttributeCommonInfo &CI, Expr *Min, Expr *Max)
Create an AMDGPUWavesPerEUAttr attribute.
bool checkMovDPPFunctionCall(CallExpr *TheCall, unsigned NumArgs, unsigned NumDataArgs)
void handleAMDGPUWavesPerEUAttr(Decl *D, const ParsedAttr &AL)
bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
void addAMDGPUWavesPerEUAttr(Decl *D, const AttributeCommonInfo &CI, Expr *Min, Expr *Max)
addAMDGPUWavePersEUAttr - Adds an amdgpu_waves_per_eu attribute to a particular declaration.
void addAMDGPUMaxNumWorkGroupsAttr(Decl *D, const AttributeCommonInfo &CI, Expr *XExpr, Expr *YExpr, Expr *ZExpr)
addAMDGPUMaxNumWorkGroupsAttr - Adds an amdgpu_max_num_work_groups attribute to a particular declarat...
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition SemaBase.cpp:61
SemaBase(Sema &S)
Definition SemaBase.cpp:7
ASTContext & getASTContext() const
Definition SemaBase.cpp:9
Sema & SemaRef
Definition SemaBase.h:40
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:854
bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T, UnexpandedParameterPackContext UPPC)
If the given type contains an unexpanded parameter pack, diagnose the error.
bool checkUInt32Argument(const AttrInfo &AI, const Expr *Expr, uint32_t &Val, unsigned Idx=UINT_MAX, bool StrictlyUnsigned=false)
If Expr is a valid integer constant, get the value of the integer expression and return success or fa...
Definition Sema.h:4827
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:334
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Stmt.cpp:346
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:752
bool evaluateRequiredTargetFeatures(llvm::StringRef RequiredFatures, const llvm::StringMap< bool > &TargetFetureMap)
Returns true if the required target features of a builtin function are enabled.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
static bool checkAMDGPUMaxNumWorkGroupsArguments(Sema &S, Expr *XExpr, Expr *YExpr, Expr *ZExpr, const AMDGPUMaxNumWorkGroupsAttr &Attr)
static bool checkAMDGPUFlatWorkGroupSizeArguments(Sema &S, Expr *MinExpr, Expr *MaxExpr, const AMDGPUFlatWorkGroupSizeAttr &Attr)
ActionResult< Expr * > ExprResult
Definition Ownership.h:249
static bool checkAMDGPUWavesPerEUArguments(Sema &S, Expr *MinExpr, Expr *MaxExpr, const AMDGPUWavesPerEUAttr &Attr)
EvalResult is a struct with detailed info about an evaluated expression.
Definition Expr.h:645
APValue Val
Val - This is the value the expression can be folded to.
Definition Expr.h:647