clang 23.0.0git
SemaPPC.cpp
Go to the documentation of this file.
1//===------ SemaPPC.cpp ------ PowerPC 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 PowerPC.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/Sema/SemaPPC.h"
15#include "clang/AST/Attr.h"
16#include "clang/AST/CharUnits.h"
17#include "clang/AST/Decl.h"
18#include "clang/AST/Type.h"
24#include "clang/Sema/Sema.h"
25#include "llvm/ADT/APSInt.h"
26#include "llvm/TargetParser/PPCTargetParser.h"
27
28namespace clang {
29
31
33 const auto *ICE = dyn_cast<ImplicitCastExpr>(Arg->IgnoreParens());
34 if (!ICE)
35 return;
36
37 const auto *DR = dyn_cast<DeclRefExpr>(ICE->getSubExpr());
38 if (!DR)
39 return;
40
41 const auto *PD = dyn_cast<ParmVarDecl>(DR->getDecl());
42 if (!PD || !PD->getType()->isRecordType())
43 return;
44
45 QualType ArgType = Arg->getType();
46 for (const FieldDecl *FD : ArgType->castAsRecordDecl()->fields()) {
47 if (const auto *AA = FD->getAttr<AlignedAttr>()) {
49 AA->getAlignment(getASTContext()));
50 if (Alignment.getQuantity() == 16) {
51 Diag(FD->getLocation(), diag::warn_not_xl_compatible) << FD;
52 Diag(Loc, diag::note_misaligned_member_used_here) << PD;
53 }
54 }
55 }
56}
57
58static bool isPPC_64Builtin(unsigned BuiltinID) {
59 // These builtins only work on PPC 64bit targets.
60 switch (BuiltinID) {
61 case PPC::BI__builtin_divde:
62 case PPC::BI__builtin_divdeu:
63 case PPC::BI__builtin_bpermd:
64 case PPC::BI__builtin_pdepd:
65 case PPC::BI__builtin_pextd:
66 case PPC::BI__builtin_ppc_cdtbcd:
67 case PPC::BI__builtin_ppc_cbcdtd:
68 case PPC::BI__builtin_ppc_addg6s:
69 case PPC::BI__builtin_ppc_ldarx:
70 case PPC::BI__builtin_ppc_stdcx:
71 case PPC::BI__builtin_ppc_tdw:
72 case PPC::BI__builtin_ppc_trapd:
73 case PPC::BI__builtin_ppc_cmpeqb:
74 case PPC::BI__builtin_ppc_setb:
75 case PPC::BI__builtin_ppc_mulhd:
76 case PPC::BI__builtin_ppc_mulhdu:
77 case PPC::BI__builtin_ppc_maddhd:
78 case PPC::BI__builtin_ppc_maddhdu:
79 case PPC::BI__builtin_ppc_maddld:
80 case PPC::BI__builtin_ppc_load8r:
81 case PPC::BI__builtin_ppc_store8r:
82 case PPC::BI__builtin_ppc_insert_exp:
83 case PPC::BI__builtin_ppc_extract_sig:
84 case PPC::BI__builtin_ppc_addex:
85 case PPC::BI__builtin_darn:
86 case PPC::BI__builtin_darn_raw:
87 case PPC::BI__builtin_ppc_compare_and_swaplp:
88 case PPC::BI__builtin_ppc_fetch_and_addlp:
89 case PPC::BI__builtin_ppc_fetch_and_andlp:
90 case PPC::BI__builtin_ppc_fetch_and_orlp:
91 case PPC::BI__builtin_ppc_fetch_and_swaplp:
92 case PPC::BI__builtin_amo_lwat:
93 case PPC::BI__builtin_amo_ldat:
94 case PPC::BI__builtin_amo_lwat_s:
95 case PPC::BI__builtin_amo_ldat_s:
96 case PPC::BI__builtin_amo_lwat_cond:
97 case PPC::BI__builtin_amo_ldat_cond:
98 case PPC::BI__builtin_amo_lwat_cond_s:
99 case PPC::BI__builtin_amo_ldat_cond_s:
100 case PPC::BI__builtin_amo_stwat:
101 case PPC::BI__builtin_amo_stdat:
102 case PPC::BI__builtin_amo_stwat_s:
103 case PPC::BI__builtin_amo_stdat_s:
104 case PPC::BI__builtin_amo_lwat_csne:
105 case PPC::BI__builtin_amo_ldat_csne:
106 case PPC::BI__builtin_amo_lwat_csne_s:
107 case PPC::BI__builtin_amo_ldat_csne_s:
108 return true;
109 }
110 return false;
111}
112
114 unsigned BuiltinID,
115 CallExpr *TheCall) {
116 ASTContext &Context = getASTContext();
117 bool IsTarget64Bit = TI.getTypeWidth(TI.getIntPtrType()) == 64;
118
119 if (isPPC_64Builtin(BuiltinID) && !IsTarget64Bit)
120 return Diag(TheCall->getBeginLoc(), diag::err_64_bit_builtin_32_bit_tgt)
121 << TheCall->getSourceRange();
122
123 // Check if the builtin requires specific target features.
124 StringRef FeatureList(Context.BuiltinInfo.getRequiredFeatures(BuiltinID));
125 if (!FeatureList.empty()) {
126 const auto *FD = SemaRef.getCurFunctionDecl(/*AllowLambda=*/true);
127 llvm::StringMap<bool> CallerFeatureMap;
128 Context.getFunctionFeatureMap(CallerFeatureMap, FD);
130 CallerFeatureMap)) {
131 // Get the builtin name from the CallExpr's callee
132 const FunctionDecl *BuiltinDecl = TheCall->getDirectCallee();
133 Diag(TheCall->getBeginLoc(), diag::err_builtin_needs_feature)
134 << (BuiltinDecl ? BuiltinDecl->getDeclName()
135 : DeclarationName(&Context.Idents.get(
136 Context.BuiltinInfo.getName(BuiltinID))))
137 << FeatureList;
138 return true;
139 }
140 }
141
142 // Common BCD type-validation helpers
143 // Emit error diagnostics and return true on success
144 // - IsTypeVecUChar: enforces vector unsigned char
145 // - IsIntType: enforces any integer type
146 // Lambdas centralize type checks for BCD builtin handlers
147
148 // Lambda 1: verify vector unsigned char type
149 auto IsTypeVecUChar = [&](QualType ArgTy, unsigned ArgIndex) -> bool {
150 QualType VecType = Context.getVectorType(Context.UnsignedCharTy, 16,
152 if (Context.hasSameType(ArgTy, VecType))
153 return true;
154
155 Diag(TheCall->getArg(ArgIndex)->getBeginLoc(),
156 diag::err_ppc_invalid_arg_type)
157 << ArgIndex << VecType << ArgTy;
158 return false;
159 };
160
161 // Lambda 2: verify integer type
162 auto IsIntType = [&](QualType ArgTy, unsigned ArgIndex) -> bool {
163 if (ArgTy->isIntegerType())
164 return true;
165
166 Diag(TheCall->getArg(ArgIndex)->getBeginLoc(),
167 diag::err_ppc_invalid_arg_type)
168 << ArgIndex << "integer" << ArgTy;
169 return false;
170 };
171
172 switch (BuiltinID) {
173 default:
174 return false;
175 case PPC::BI__builtin_ppc_bcdsetsign: {
176 // Arg0 must be vector unsigned char
177 if (!IsTypeVecUChar(TheCall->getArg(0)->getType(), 0))
178 return false;
179
180 // Restrict Arg1 constant range (0–1)
181 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1);
182 }
183 case PPC::BI__builtin_ppc_national2packed:
184 case PPC::BI__builtin_ppc_packed2zoned:
185 case PPC::BI__builtin_ppc_zoned2packed:
186 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1);
187 case PPC::BI__builtin_ppc_bcdshift:
188 case PPC::BI__builtin_ppc_bcdshiftround:
189 case PPC::BI__builtin_ppc_bcdtruncate: {
190
191 // Arg0 must be vector unsigned char
192 if (!IsTypeVecUChar(TheCall->getArg(0)->getType(), 0))
193 return false;
194
195 // Arg1 must be integer type
196 if (!IsIntType(TheCall->getArg(1)->getType(), 1))
197 return false;
198
199 // Restrict Arg2 constant range (0–1)
200 return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 1);
201 }
202 case PPC::BI__builtin_altivec_crypto_vshasigmaw:
203 case PPC::BI__builtin_altivec_crypto_vshasigmad:
204 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) ||
205 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 15);
206 case PPC::BI__builtin_altivec_dss:
207 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3);
208 case PPC::BI__builtin_tbegin:
209 case PPC::BI__builtin_tend:
210 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 1);
211 case PPC::BI__builtin_tsr:
212 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 7);
213 case PPC::BI__builtin_tabortwc:
214 case PPC::BI__builtin_tabortdc:
215 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 31);
216 case PPC::BI__builtin_tabortwci:
217 case PPC::BI__builtin_tabortdci:
218 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 31) ||
219 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31);
220 // According to GCC 'Basic PowerPC Built-in Functions Available on ISA 2.05',
221 // __builtin_(un)pack_longdouble are available only if long double uses IBM
222 // extended double representation.
223 case PPC::BI__builtin_unpack_longdouble:
224 if (SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1))
225 return true;
226 [[fallthrough]];
227 case PPC::BI__builtin_pack_longdouble:
228 if (&TI.getLongDoubleFormat() != &llvm::APFloat::PPCDoubleDouble())
229 return Diag(TheCall->getBeginLoc(), diag::err_ppc_builtin_requires_abi)
230 << "ibmlongdouble";
231 return false;
232 case PPC::BI__builtin_altivec_dst:
233 case PPC::BI__builtin_altivec_dstt:
234 case PPC::BI__builtin_altivec_dstst:
235 case PPC::BI__builtin_altivec_dststt:
236 return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3);
237 case PPC::BI__builtin_vsx_xxpermdi:
238 case PPC::BI__builtin_vsx_xxsldwi:
239 return BuiltinVSX(TheCall);
240 case PPC::BI__builtin_unpack_vector_int128:
241 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1);
242 case PPC::BI__builtin_altivec_vgnb:
243 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 2, 7);
244 case PPC::BI__builtin_vsx_xxeval:
245 return SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 255);
246 case PPC::BI__builtin_altivec_vsldbi:
247 return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 7);
248 case PPC::BI__builtin_altivec_vsrdbi:
249 return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 7);
250 case PPC::BI__builtin_vsx_xxpermx:
251 return SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 7);
252 case PPC::BI__builtin_altivec_vupkint4tobf16:
253 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 3);
254 case PPC::BI__builtin_altivec_vupkint8tobf16:
255 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1);
256 case PPC::BI__builtin_altivec_vupkint4tofp32:
257 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 7);
258 case PPC::BI__builtin_altivec_vupkint8tofp32:
259 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 3);
260 case PPC::BI__builtin_ppc_tw:
261 case PPC::BI__builtin_ppc_tdw:
262 return SemaRef.BuiltinConstantArgRange(TheCall, 2, 1, 31);
263 case PPC::BI__builtin_ppc_cmprb:
264 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 1);
265 // For __rlwnm, __rlwimi and __rldimi, the last parameter mask must
266 // be a constant that represents a contiguous bit field.
267 case PPC::BI__builtin_ppc_rlwnm:
268 return SemaRef.ValueIsRunOfOnes(TheCall, 2);
269 case PPC::BI__builtin_ppc_rlwimi:
270 return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31) ||
271 SemaRef.ValueIsRunOfOnes(TheCall, 3);
272 case PPC::BI__builtin_ppc_rldimi:
273 return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 63) ||
274 SemaRef.ValueIsRunOfOnes(TheCall, 3);
275 case PPC::BI__builtin_ppc_addex: {
276 if (SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3))
277 return true;
278 // Output warning for reserved values 1 to 3.
279 int ArgValue =
280 TheCall->getArg(2)->getIntegerConstantExpr(Context)->getSExtValue();
281 if (ArgValue != 0)
282 Diag(TheCall->getBeginLoc(), diag::warn_argument_undefined_behaviour)
283 << ArgValue;
284 return false;
285 }
286 case PPC::BI__builtin_ppc_mtfsb0:
287 case PPC::BI__builtin_ppc_mtfsb1:
288 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 31);
289 case PPC::BI__builtin_ppc_mtfsf:
290 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 255);
291 case PPC::BI__builtin_ppc_mtfsfi:
292 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 7) ||
293 SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 15);
294 case PPC::BI__builtin_ppc_alignx:
295 return SemaRef.BuiltinConstantArgPower2(TheCall, 0);
296 case PPC::BI__builtin_ppc_rdlam:
297 return SemaRef.ValueIsRunOfOnes(TheCall, 2);
298 case PPC::BI__builtin_vsx_ldrmb:
299 case PPC::BI__builtin_vsx_strmb:
300 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 1, 16);
301 case PPC::BI__builtin_altivec_vcntmbb:
302 case PPC::BI__builtin_altivec_vcntmbh:
303 case PPC::BI__builtin_altivec_vcntmbw:
304 case PPC::BI__builtin_altivec_vcntmbd:
305 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1);
306 case PPC::BI__builtin_vsx_xxgenpcvbm:
307 case PPC::BI__builtin_vsx_xxgenpcvhm:
308 case PPC::BI__builtin_vsx_xxgenpcvwm:
309 case PPC::BI__builtin_vsx_xxgenpcvdm:
310 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 3);
311 case PPC::BI__builtin_ppc_test_data_class: {
312 // Check if the first argument of the __builtin_ppc_test_data_class call is
313 // valid. The argument must be 'float' or 'double' or '__float128'.
314 QualType ArgType = TheCall->getArg(0)->getType();
315 if (ArgType != QualType(Context.FloatTy) &&
316 ArgType != QualType(Context.DoubleTy) &&
317 ArgType != QualType(Context.Float128Ty))
318 return Diag(TheCall->getBeginLoc(),
319 diag::err_ppc_invalid_test_data_class_type);
320 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 127);
321 }
322 case PPC::BI__builtin_ppc_maxfe:
323 case PPC::BI__builtin_ppc_minfe:
324 case PPC::BI__builtin_ppc_maxfl:
325 case PPC::BI__builtin_ppc_minfl:
326 case PPC::BI__builtin_ppc_maxfs:
327 case PPC::BI__builtin_ppc_minfs: {
328 if (Context.getTargetInfo().getTriple().isOSAIX() &&
329 (BuiltinID == PPC::BI__builtin_ppc_maxfe ||
330 BuiltinID == PPC::BI__builtin_ppc_minfe))
331 return Diag(TheCall->getBeginLoc(), diag::err_target_unsupported_type)
332 << "builtin" << true << 128 << QualType(Context.LongDoubleTy)
333 << false << Context.getTargetInfo().getTriple().str();
334 // Argument type should be exact.
335 QualType ArgType = QualType(Context.LongDoubleTy);
336 if (BuiltinID == PPC::BI__builtin_ppc_maxfl ||
337 BuiltinID == PPC::BI__builtin_ppc_minfl)
338 ArgType = QualType(Context.DoubleTy);
339 else if (BuiltinID == PPC::BI__builtin_ppc_maxfs ||
340 BuiltinID == PPC::BI__builtin_ppc_minfs)
341 ArgType = QualType(Context.FloatTy);
342 for (unsigned I = 0, E = TheCall->getNumArgs(); I < E; ++I)
343 if (TheCall->getArg(I)->getType() != ArgType)
344 return Diag(TheCall->getBeginLoc(),
345 diag::err_typecheck_convert_incompatible)
346 << TheCall->getArg(I)->getType() << ArgType << 1 << 0 << 0;
347 return false;
348 }
349#define CUSTOM_BUILTIN(Name, Intr, Types, Acc, Feature) \
350 case PPC::BI__builtin_##Name: \
351 return BuiltinPPCMMACall(TheCall, BuiltinID, Types);
352#include "clang/Basic/BuiltinsPPC.def"
353 case PPC::BI__builtin_amo_lwat:
354 case PPC::BI__builtin_amo_ldat:
355 case PPC::BI__builtin_amo_lwat_s:
356 case PPC::BI__builtin_amo_ldat_s: {
357 llvm::APSInt Result;
358 if (SemaRef.BuiltinConstantArg(TheCall, 2, Result))
359 return true;
360 unsigned Val = Result.getZExtValue();
361
362 bool IsUnsigned = (BuiltinID == PPC::BI__builtin_amo_lwat ||
363 BuiltinID == PPC::BI__builtin_amo_ldat);
364
365 bool IsValid = IsUnsigned
366 ? llvm::is_contained({0u, 1u, 2u, 3u, 4u, 6u, 8u}, Val)
367 : llvm::is_contained({0u, 5u, 7u, 8u}, Val);
368
369 if (IsValid)
370 return false;
371
372 Expr *Arg = TheCall->getArg(2);
373 return SemaRef.Diag(Arg->getBeginLoc(), diag::err_argument_invalid_range)
374 << toString(Result, 10) << (IsUnsigned ? "0-4, 6" : "0, 5, 7") << "8"
375 << Arg->getSourceRange();
376 }
377 case PPC::BI__builtin_amo_lwat_cond:
378 case PPC::BI__builtin_amo_ldat_cond:
379 case PPC::BI__builtin_amo_lwat_cond_s:
380 case PPC::BI__builtin_amo_ldat_cond_s: {
381 llvm::APSInt Result;
382 if (SemaRef.BuiltinConstantArg(TheCall, 1, Result))
383 return true;
384 unsigned Val = Result.getZExtValue();
385 if (llvm::is_contained({24u, 25u, 28u}, Val))
386 return false;
387
388 Expr *Arg = TheCall->getArg(1);
389 return SemaRef.Diag(Arg->getBeginLoc(), diag::err_argument_invalid_range)
390 << toString(Result, 10) << "24, 25" << "28" << Arg->getSourceRange();
391 }
392 case PPC::BI__builtin_amo_stwat:
393 case PPC::BI__builtin_amo_stdat:
394 case PPC::BI__builtin_amo_stwat_s:
395 case PPC::BI__builtin_amo_stdat_s: {
396 llvm::APSInt Result;
397 if (SemaRef.BuiltinConstantArg(TheCall, 2, Result))
398 return true;
399 unsigned Val = Result.getZExtValue();
400
401 bool IsUnsigned = (BuiltinID == PPC::BI__builtin_amo_stwat ||
402 BuiltinID == PPC::BI__builtin_amo_stdat);
403
404 bool IsValid = IsUnsigned
405 ? llvm::is_contained({0u, 1u, 2u, 3u, 4u, 6u, 24u}, Val)
406 : llvm::is_contained({0u, 5u, 7u, 24u}, Val);
407
408 if (IsValid)
409 return false;
410
411 Expr *Arg = TheCall->getArg(2);
412 return SemaRef.Diag(Arg->getBeginLoc(), diag::err_argument_invalid_range)
413 << toString(Result, 10) << (IsUnsigned ? "0-4, 6" : "0, 5, 7")
414 << "24" << Arg->getSourceRange();
415 }
416 }
417 llvm_unreachable("must return from switch");
418}
419
420// Check if the given type is a non-pointer PPC MMA type. This function is used
421// in Sema to prevent invalid uses of restricted PPC MMA types.
423 ASTContext &Context = getASTContext();
424 if (Type->isPointerType() || Type->isArrayType())
425 return false;
426
427 QualType CoreType = Type.getCanonicalType().getUnqualifiedType();
428#define PPC_VECTOR_TYPE(Name, Id, Size) || CoreType == Context.Id##Ty
429 if (false
430#include "clang/Basic/PPCTypes.def"
431 ) {
432 Diag(TypeLoc, diag::err_ppc_invalid_use_mma_type);
433 return true;
434 }
435 return false;
436}
437
438/// DecodePPCMMATypeFromStr - This decodes one PPC MMA type descriptor from Str,
439/// advancing the pointer over the consumed characters. The decoded type is
440/// returned. If the decoded type represents a constant integer with a
441/// constraint on its value then Mask is set to that value. The type descriptors
442/// used in Str are specific to PPC MMA builtins and are documented in the file
443/// defining the PPC builtins.
444static QualType DecodePPCMMATypeFromStr(ASTContext &Context, const char *&Str,
445 unsigned &Mask) {
446 bool RequireICE = false;
448 switch (*Str++) {
449 case 'V':
450 return Context.getVectorType(Context.UnsignedCharTy, 16,
452 case 'i': {
453 char *End;
454 unsigned size = strtoul(Str, &End, 10);
455 assert(End != Str && "Missing constant parameter constraint");
456 Str = End;
457 Mask = size;
458 return Context.IntTy;
459 }
460 case 'W': {
461 char *End;
462 unsigned size = strtoul(Str, &End, 10);
463 assert(End != Str && "Missing PowerPC MMA type size");
464 Str = End;
466 switch (size) {
467#define PPC_VECTOR_TYPE(typeName, Id, size) \
468 case size: \
469 Type = Context.Id##Ty; \
470 break;
471#include "clang/Basic/PPCTypes.def"
472 default:
473 llvm_unreachable("Invalid PowerPC MMA vector type");
474 }
475 bool CheckVectorArgs = false;
476 while (!CheckVectorArgs) {
477 switch (*Str++) {
478 case '*':
479 Type = Context.getPointerType(Type);
480 break;
481 case 'C':
482 Type = Type.withConst();
483 break;
484 default:
485 CheckVectorArgs = true;
486 --Str;
487 break;
488 }
489 }
490 return Type;
491 }
492 default:
493 return Context.DecodeTypeStr(--Str, Context, Error, RequireICE, true);
494 }
495}
496
497bool SemaPPC::BuiltinPPCMMACall(CallExpr *TheCall, unsigned BuiltinID,
498 const char *TypeStr) {
499
500 assert((TypeStr[0] != '\0') &&
501 "Invalid types in PPC MMA builtin declaration");
502
503 ASTContext &Context = getASTContext();
504 unsigned Mask = 0;
505 unsigned ArgNum = 0;
506
507 // The first type in TypeStr is the type of the value returned by the
508 // builtin. So we first read that type and change the type of TheCall.
509 QualType type = DecodePPCMMATypeFromStr(Context, TypeStr, Mask);
510 TheCall->setType(type);
511
512 while (*TypeStr != '\0') {
513 Mask = 0;
514 QualType ExpectedType = DecodePPCMMATypeFromStr(Context, TypeStr, Mask);
515 if (ArgNum >= TheCall->getNumArgs()) {
516 ArgNum++;
517 break;
518 }
519
520 Expr *Arg = TheCall->getArg(ArgNum);
521 QualType PassedType = Arg->getType();
522 QualType StrippedRVType = PassedType.getCanonicalType();
523
524 // Strip Restrict/Volatile qualifiers.
525 if (StrippedRVType.isRestrictQualified() ||
526 StrippedRVType.isVolatileQualified())
527 StrippedRVType = StrippedRVType.getCanonicalType().getUnqualifiedType();
528
529 // The only case where the argument type and expected type are allowed to
530 // mismatch is if the argument type is a non-void pointer (or array) and
531 // expected type is a void pointer.
532 if (StrippedRVType != ExpectedType)
533 if (!(ExpectedType->isVoidPointerType() &&
534 (StrippedRVType->isPointerType() || StrippedRVType->isArrayType())))
535 return Diag(Arg->getBeginLoc(),
536 diag::err_typecheck_convert_incompatible)
537 << PassedType << ExpectedType << 1 << 0 << 0;
538
539 // If the value of the Mask is not 0, we have a constraint in the size of
540 // the integer argument so here we ensure the argument is a constant that
541 // is in the valid range.
542 if (Mask != 0 &&
543 SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, Mask, true))
544 return true;
545
546 ArgNum++;
547 }
548
549 // In case we exited early from the previous loop, there are other types to
550 // read from TypeStr. So we need to read them all to ensure we have the right
551 // number of arguments in TheCall and if it is not the case, to display a
552 // better error message.
553 while (*TypeStr != '\0') {
554 (void)DecodePPCMMATypeFromStr(Context, TypeStr, Mask);
555 ArgNum++;
556 }
557 if (SemaRef.checkArgCount(TheCall, ArgNum))
558 return true;
559
560 return false;
561}
562
564 unsigned ExpectedNumArgs = 3;
565 if (SemaRef.checkArgCount(TheCall, ExpectedNumArgs))
566 return true;
567
568 // Check the third argument is a compile time constant
569 if (!TheCall->getArg(2)->isIntegerConstantExpr(getASTContext()))
570 return Diag(TheCall->getBeginLoc(),
571 diag::err_vsx_builtin_nonconstant_argument)
572 << 3 /* argument index */ << TheCall->getDirectCallee()
573 << SourceRange(TheCall->getArg(2)->getBeginLoc(),
574 TheCall->getArg(2)->getEndLoc());
575
576 QualType Arg1Ty = TheCall->getArg(0)->getType();
577 QualType Arg2Ty = TheCall->getArg(1)->getType();
578
579 // Check the type of argument 1 and argument 2 are vectors.
580 SourceLocation BuiltinLoc = TheCall->getBeginLoc();
581 if ((!Arg1Ty->isVectorType() && !Arg1Ty->isDependentType()) ||
582 (!Arg2Ty->isVectorType() && !Arg2Ty->isDependentType())) {
583 return Diag(BuiltinLoc, diag::err_vec_builtin_non_vector)
584 << TheCall->getDirectCallee() << /*isMorethantwoArgs*/ false
585 << SourceRange(TheCall->getArg(0)->getBeginLoc(),
586 TheCall->getArg(1)->getEndLoc());
587 }
588
589 // Check the first two arguments are the same type.
590 if (!getASTContext().hasSameUnqualifiedType(Arg1Ty, Arg2Ty)) {
591 return Diag(BuiltinLoc, diag::err_vec_builtin_incompatible_vector)
592 << TheCall->getDirectCallee() << /*isMorethantwoArgs*/ false
593 << SourceRange(TheCall->getArg(0)->getBeginLoc(),
594 TheCall->getArg(1)->getEndLoc());
595 }
596
597 // When default clang type checking is turned off and the customized type
598 // checking is used, the returning type of the function must be explicitly
599 // set. Otherwise it is _Bool by default.
600 TheCall->setType(Arg1Ty);
601
602 return false;
603}
604
608 SourceLocation AttrLoc) {
609 using namespace DiagAttrParams;
610
611 assert(Params.size() == Locs.size() &&
612 "Mismatch between number of string parameters and locations");
613
615 bool HasDefault = false;
616 bool HasComma = false;
617 for (unsigned I = 0, E = Params.size(); I < E; ++I) {
618 const StringRef Param = Params[I].trim();
619 const SourceLocation &Loc = Locs[I];
620
621 if (Param.empty() || Param.ends_with(','))
622 return Diag(Loc, diag::warn_unsupported_target_attribute)
623 << Unsupported << None << "" << TargetClones;
624
625 if (Param.contains(','))
626 HasComma = true;
627
628 StringRef LHS;
629 StringRef RHS = Param;
630 do {
631 std::tie(LHS, RHS) = RHS.split(',');
632 LHS = LHS.trim();
633 const SourceLocation &CurLoc =
634 Loc.getLocWithOffset(LHS.data() - Param.data());
635
636 if (LHS.starts_with("cpu=")) {
637 StringRef CPUStr = LHS.drop_front(sizeof("cpu=") - 1);
638 if (!TargetInfo.isValidCPUName(CPUStr))
639 return Diag(CurLoc, diag::warn_unsupported_target_attribute)
640 << Unknown << CPU << CPUStr << TargetClones;
641 else if (!TargetInfo.validateCpuIs(CPUStr))
642 return Diag(CurLoc, diag::warn_unsupported_target_attribute)
643 << Unsupported << CPU << CPUStr << TargetClones;
644 } else if (LHS == "default") {
645 HasDefault = true;
646 } else {
647 // it's a feature string, but not supported yet.
648 return Diag(CurLoc, diag::warn_unsupported_target_attribute)
649 << Unsupported << None << LHS << TargetClones;
650 }
651 SmallString<64> CPU;
652 if (LHS.starts_with("cpu=")) {
653 CPU.append("cpu=");
654 CPU.append(
655 llvm::PPC::normalizeCPUName(LHS.drop_front(sizeof("cpu=") - 1)));
656 LHS = CPU.str();
657 }
658 if (llvm::is_contained(NewParams, LHS)) {
659 Diag(CurLoc, diag::warn_target_clone_duplicate_options);
660 continue;
661 }
662 NewParams.push_back(LHS);
663 } while (!RHS.empty());
664 }
665 if (HasComma && Params.size() > 1)
666 Diag(Locs[0], diag::warn_target_clone_mixed_values);
667
668 if (!HasDefault)
669 return Diag(AttrLoc, diag::err_target_clone_must_have_default);
670
671 return false;
672}
673} // namespace clang
Defines the clang::ASTContext interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file declares semantic analysis functions specific to PowerPC.
Defines the clang::SourceLocation class and associated facilities.
Enumerates target-specific builtins in their own namespaces within namespace clang.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:226
const TargetInfo & getTargetInfo() const
Definition ASTContext.h:917
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
@ GE_None
No error.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2946
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition Expr.h:3150
SourceLocation getBeginLoc() const
Definition Expr.h:3280
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition Expr.h:3129
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition Expr.h:3137
CharUnits - This is an opaque type for sizes expressed in character units.
Definition CharUnits.h:38
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition CharUnits.h:185
The name of a declaration.
This represents one expression.
Definition Expr.h:112
bool isIntegerConstantExpr(const ASTContext &Ctx) const
void setType(QualType t)
Definition Expr.h:145
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3086
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
QualType getType() const
Definition Expr.h:144
Represents a member of a struct/union/class.
Definition Decl.h:3175
Represents a function declaration or definition.
Definition Decl.h:2015
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:340
A (possibly-)qualified type.
Definition TypeBase.h:937
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
Definition TypeBase.h:8515
bool isRestrictQualified() const
Determine whether this type is restrict-qualified.
Definition TypeBase.h:8509
QualType getCanonicalType() const
Definition TypeBase.h:8483
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition TypeBase.h:8525
SemaBase(Sema &S)
Definition SemaBase.cpp:7
ASTContext & getASTContext() const
Definition SemaBase.cpp:9
Sema & SemaRef
Definition SemaBase.h:40
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Definition SemaBase.cpp:61
bool checkTargetClonesAttr(const SmallVectorImpl< StringRef > &Params, const SmallVectorImpl< SourceLocation > &Locs, SmallVectorImpl< SmallString< 64 > > &NewParams, SourceLocation AttrLoc)
Definition SemaPPC.cpp:605
bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
Definition SemaPPC.cpp:113
void checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg)
Definition SemaPPC.cpp:32
SemaPPC(Sema &S)
Definition SemaPPC.cpp:30
bool BuiltinPPCMMACall(CallExpr *TheCall, unsigned BuiltinID, const char *TypeDesc)
BuiltinPPCMMACall - Check the call to a PPC MMA builtin for validity.
Definition SemaPPC.cpp:497
bool BuiltinVSX(CallExpr *TheCall)
Definition SemaPPC.cpp:563
bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc)
Definition SemaPPC.cpp:422
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:868
Encodes a location in the source.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
A trivial tuple used to represent a source range.
SourceLocation getEndLoc() const LLVM_READONLY
Definition Stmt.cpp:367
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:343
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Stmt.cpp:355
Exposes information about the current target.
Definition TargetInfo.h:227
virtual bool validateCpuIs(StringRef Name) const
unsigned getTypeWidth(IntType T) const
Return the width (in bits) of the specified integer type enum.
IntType getIntPtrType() const
Definition TargetInfo.h:415
const llvm::fltSemantics & getLongDoubleFormat() const
Definition TargetInfo.h:810
virtual bool isValidCPUName(StringRef Name) const
Determine whether this TargetInfo supports the given CPU name.
Base wrapper for a particular "section" of type source info.
Definition TypeLoc.h:59
The base class of the type hierarchy.
Definition TypeBase.h:1866
bool isArrayType() const
Definition TypeBase.h:8767
bool isPointerType() const
Definition TypeBase.h:8668
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition TypeBase.h:9078
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition TypeBase.h:2832
bool isVectorType() const
Definition TypeBase.h:8807
Defines the clang::TargetInfo interface.
bool evaluateRequiredTargetFeatures(llvm::StringRef RequiredFatures, const llvm::StringMap< bool > &TargetFetureMap)
Returns true if the required target features of a builtin function are enabled.
Enums for the diagnostics of target, target_version and target_clones.
Definition Sema.h:854
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
The JSON file list parser is used to communicate input to InstallAPI.
static bool isPPC_64Builtin(unsigned BuiltinID)
Definition SemaPPC.cpp:58
@ Result
The result type of a method or function.
Definition TypeBase.h:905
llvm::Expected< QualType > ExpectedType
static QualType DecodePPCMMATypeFromStr(ASTContext &Context, const char *&Str, unsigned &Mask)
DecodePPCMMATypeFromStr - This decodes one PPC MMA type descriptor from Str, advancing the pointer ov...
Definition SemaPPC.cpp:444
@ AltiVecVector
is AltiVec vector
Definition TypeBase.h:4189
@ None
The alignment was not explicit in code.
Definition ASTContext.h:179