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"
23#include "clang/Sema/Sema.h"
24#include "llvm/ADT/APSInt.h"
25
26namespace clang {
27
29
31 const auto *ICE = dyn_cast<ImplicitCastExpr>(Arg->IgnoreParens());
32 if (!ICE)
33 return;
34
35 const auto *DR = dyn_cast<DeclRefExpr>(ICE->getSubExpr());
36 if (!DR)
37 return;
38
39 const auto *PD = dyn_cast<ParmVarDecl>(DR->getDecl());
40 if (!PD || !PD->getType()->isRecordType())
41 return;
42
43 QualType ArgType = Arg->getType();
44 for (const FieldDecl *FD : ArgType->castAsRecordDecl()->fields()) {
45 if (const auto *AA = FD->getAttr<AlignedAttr>()) {
47 AA->getAlignment(getASTContext()));
48 if (Alignment.getQuantity() == 16) {
49 Diag(FD->getLocation(), diag::warn_not_xl_compatible) << FD;
50 Diag(Loc, diag::note_misaligned_member_used_here) << PD;
51 }
52 }
53 }
54}
55
56static bool isPPC_64Builtin(unsigned BuiltinID) {
57 // These builtins only work on PPC 64bit targets.
58 switch (BuiltinID) {
59 case PPC::BI__builtin_divde:
60 case PPC::BI__builtin_divdeu:
61 case PPC::BI__builtin_bpermd:
62 case PPC::BI__builtin_pdepd:
63 case PPC::BI__builtin_pextd:
64 case PPC::BI__builtin_ppc_cdtbcd:
65 case PPC::BI__builtin_ppc_cbcdtd:
66 case PPC::BI__builtin_ppc_addg6s:
67 case PPC::BI__builtin_ppc_ldarx:
68 case PPC::BI__builtin_ppc_stdcx:
69 case PPC::BI__builtin_ppc_tdw:
70 case PPC::BI__builtin_ppc_trapd:
71 case PPC::BI__builtin_ppc_cmpeqb:
72 case PPC::BI__builtin_ppc_setb:
73 case PPC::BI__builtin_ppc_mulhd:
74 case PPC::BI__builtin_ppc_mulhdu:
75 case PPC::BI__builtin_ppc_maddhd:
76 case PPC::BI__builtin_ppc_maddhdu:
77 case PPC::BI__builtin_ppc_maddld:
78 case PPC::BI__builtin_ppc_load8r:
79 case PPC::BI__builtin_ppc_store8r:
80 case PPC::BI__builtin_ppc_insert_exp:
81 case PPC::BI__builtin_ppc_extract_sig:
82 case PPC::BI__builtin_ppc_addex:
83 case PPC::BI__builtin_darn:
84 case PPC::BI__builtin_darn_raw:
85 case PPC::BI__builtin_ppc_compare_and_swaplp:
86 case PPC::BI__builtin_ppc_fetch_and_addlp:
87 case PPC::BI__builtin_ppc_fetch_and_andlp:
88 case PPC::BI__builtin_ppc_fetch_and_orlp:
89 case PPC::BI__builtin_ppc_fetch_and_swaplp:
90 case PPC::BI__builtin_amo_lwat:
91 case PPC::BI__builtin_amo_ldat:
92 case PPC::BI__builtin_amo_lwat_s:
93 case PPC::BI__builtin_amo_ldat_s:
94 case PPC::BI__builtin_amo_lwat_cond:
95 case PPC::BI__builtin_amo_ldat_cond:
96 case PPC::BI__builtin_amo_lwat_cond_s:
97 case PPC::BI__builtin_amo_ldat_cond_s:
98 case PPC::BI__builtin_amo_stwat:
99 case PPC::BI__builtin_amo_stdat:
100 case PPC::BI__builtin_amo_stwat_s:
101 case PPC::BI__builtin_amo_stdat_s:
102 return true;
103 }
104 return false;
105}
106
108 unsigned BuiltinID,
109 CallExpr *TheCall) {
110 ASTContext &Context = getASTContext();
111 bool IsTarget64Bit = TI.getTypeWidth(TI.getIntPtrType()) == 64;
112
113 if (isPPC_64Builtin(BuiltinID) && !IsTarget64Bit)
114 return Diag(TheCall->getBeginLoc(), diag::err_64_bit_builtin_32_bit_tgt)
115 << TheCall->getSourceRange();
116
117 // Common BCD type-validation helpers
118 // Emit error diagnostics and return true on success
119 // - IsTypeVecUChar: enforces vector unsigned char
120 // - IsIntType: enforces any integer type
121 // Lambdas centralize type checks for BCD builtin handlers
122
123 // Lambda 1: verify vector unsigned char type
124 auto IsTypeVecUChar = [&](QualType ArgTy, unsigned ArgIndex) -> bool {
125 QualType VecType = Context.getVectorType(Context.UnsignedCharTy, 16,
127 if (Context.hasSameType(ArgTy, VecType))
128 return true;
129
130 Diag(TheCall->getArg(ArgIndex)->getBeginLoc(),
131 diag::err_ppc_invalid_arg_type)
132 << ArgIndex << VecType << ArgTy;
133 return false;
134 };
135
136 // Lambda 2: verify integer type
137 auto IsIntType = [&](QualType ArgTy, unsigned ArgIndex) -> bool {
138 if (ArgTy->isIntegerType())
139 return true;
140
141 Diag(TheCall->getArg(ArgIndex)->getBeginLoc(),
142 diag::err_ppc_invalid_arg_type)
143 << ArgIndex << "integer" << ArgTy;
144 return false;
145 };
146
147 switch (BuiltinID) {
148 default:
149 return false;
150 case PPC::BI__builtin_ppc_bcdsetsign: {
151 // Arg0 must be vector unsigned char
152 if (!IsTypeVecUChar(TheCall->getArg(0)->getType(), 0))
153 return false;
154
155 // Restrict Arg1 constant range (0–1)
156 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1);
157 }
158 case PPC::BI__builtin_ppc_national2packed:
159 case PPC::BI__builtin_ppc_packed2zoned:
160 case PPC::BI__builtin_ppc_zoned2packed:
161 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1);
162 case PPC::BI__builtin_ppc_bcdshift:
163 case PPC::BI__builtin_ppc_bcdshiftround:
164 case PPC::BI__builtin_ppc_bcdtruncate: {
165
166 // Arg0 must be vector unsigned char
167 if (!IsTypeVecUChar(TheCall->getArg(0)->getType(), 0))
168 return false;
169
170 // Arg1 must be integer type
171 if (!IsIntType(TheCall->getArg(1)->getType(), 1))
172 return false;
173
174 // Restrict Arg2 constant range (0–1)
175 return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 1);
176 }
177 case PPC::BI__builtin_altivec_crypto_vshasigmaw:
178 case PPC::BI__builtin_altivec_crypto_vshasigmad:
179 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) ||
180 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 15);
181 case PPC::BI__builtin_altivec_dss:
182 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3);
183 case PPC::BI__builtin_tbegin:
184 case PPC::BI__builtin_tend:
185 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 1);
186 case PPC::BI__builtin_tsr:
187 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 7);
188 case PPC::BI__builtin_tabortwc:
189 case PPC::BI__builtin_tabortdc:
190 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 31);
191 case PPC::BI__builtin_tabortwci:
192 case PPC::BI__builtin_tabortdci:
193 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 31) ||
194 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31);
195 // According to GCC 'Basic PowerPC Built-in Functions Available on ISA 2.05',
196 // __builtin_(un)pack_longdouble are available only if long double uses IBM
197 // extended double representation.
198 case PPC::BI__builtin_unpack_longdouble:
199 if (SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1))
200 return true;
201 [[fallthrough]];
202 case PPC::BI__builtin_pack_longdouble:
203 if (&TI.getLongDoubleFormat() != &llvm::APFloat::PPCDoubleDouble())
204 return Diag(TheCall->getBeginLoc(), diag::err_ppc_builtin_requires_abi)
205 << "ibmlongdouble";
206 return false;
207 case PPC::BI__builtin_altivec_dst:
208 case PPC::BI__builtin_altivec_dstt:
209 case PPC::BI__builtin_altivec_dstst:
210 case PPC::BI__builtin_altivec_dststt:
211 return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3);
212 case PPC::BI__builtin_vsx_xxpermdi:
213 case PPC::BI__builtin_vsx_xxsldwi:
214 return BuiltinVSX(TheCall);
215 case PPC::BI__builtin_unpack_vector_int128:
216 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1);
217 case PPC::BI__builtin_altivec_vgnb:
218 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 2, 7);
219 case PPC::BI__builtin_vsx_xxeval:
220 return SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 255);
221 case PPC::BI__builtin_altivec_vsldbi:
222 return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 7);
223 case PPC::BI__builtin_altivec_vsrdbi:
224 return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 7);
225 case PPC::BI__builtin_vsx_xxpermx:
226 return SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 7);
227 case PPC::BI__builtin_ppc_tw:
228 case PPC::BI__builtin_ppc_tdw:
229 return SemaRef.BuiltinConstantArgRange(TheCall, 2, 1, 31);
230 case PPC::BI__builtin_ppc_cmprb:
231 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 1);
232 // For __rlwnm, __rlwimi and __rldimi, the last parameter mask must
233 // be a constant that represents a contiguous bit field.
234 case PPC::BI__builtin_ppc_rlwnm:
235 return SemaRef.ValueIsRunOfOnes(TheCall, 2);
236 case PPC::BI__builtin_ppc_rlwimi:
237 return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31) ||
238 SemaRef.ValueIsRunOfOnes(TheCall, 3);
239 case PPC::BI__builtin_ppc_rldimi:
240 return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 63) ||
241 SemaRef.ValueIsRunOfOnes(TheCall, 3);
242 case PPC::BI__builtin_ppc_addex: {
243 if (SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3))
244 return true;
245 // Output warning for reserved values 1 to 3.
246 int ArgValue =
247 TheCall->getArg(2)->getIntegerConstantExpr(Context)->getSExtValue();
248 if (ArgValue != 0)
249 Diag(TheCall->getBeginLoc(), diag::warn_argument_undefined_behaviour)
250 << ArgValue;
251 return false;
252 }
253 case PPC::BI__builtin_ppc_mtfsb0:
254 case PPC::BI__builtin_ppc_mtfsb1:
255 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 31);
256 case PPC::BI__builtin_ppc_mtfsf:
257 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 255);
258 case PPC::BI__builtin_ppc_mtfsfi:
259 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 7) ||
260 SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 15);
261 case PPC::BI__builtin_ppc_alignx:
262 return SemaRef.BuiltinConstantArgPower2(TheCall, 0);
263 case PPC::BI__builtin_ppc_rdlam:
264 return SemaRef.ValueIsRunOfOnes(TheCall, 2);
265 case PPC::BI__builtin_vsx_ldrmb:
266 case PPC::BI__builtin_vsx_strmb:
267 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 1, 16);
268 case PPC::BI__builtin_altivec_vcntmbb:
269 case PPC::BI__builtin_altivec_vcntmbh:
270 case PPC::BI__builtin_altivec_vcntmbw:
271 case PPC::BI__builtin_altivec_vcntmbd:
272 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1);
273 case PPC::BI__builtin_vsx_xxgenpcvbm:
274 case PPC::BI__builtin_vsx_xxgenpcvhm:
275 case PPC::BI__builtin_vsx_xxgenpcvwm:
276 case PPC::BI__builtin_vsx_xxgenpcvdm:
277 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 3);
278 case PPC::BI__builtin_ppc_test_data_class: {
279 // Check if the first argument of the __builtin_ppc_test_data_class call is
280 // valid. The argument must be 'float' or 'double' or '__float128'.
281 QualType ArgType = TheCall->getArg(0)->getType();
282 if (ArgType != QualType(Context.FloatTy) &&
283 ArgType != QualType(Context.DoubleTy) &&
284 ArgType != QualType(Context.Float128Ty))
285 return Diag(TheCall->getBeginLoc(),
286 diag::err_ppc_invalid_test_data_class_type);
287 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 127);
288 }
289 case PPC::BI__builtin_ppc_maxfe:
290 case PPC::BI__builtin_ppc_minfe:
291 case PPC::BI__builtin_ppc_maxfl:
292 case PPC::BI__builtin_ppc_minfl:
293 case PPC::BI__builtin_ppc_maxfs:
294 case PPC::BI__builtin_ppc_minfs: {
295 if (Context.getTargetInfo().getTriple().isOSAIX() &&
296 (BuiltinID == PPC::BI__builtin_ppc_maxfe ||
297 BuiltinID == PPC::BI__builtin_ppc_minfe))
298 return Diag(TheCall->getBeginLoc(), diag::err_target_unsupported_type)
299 << "builtin" << true << 128 << QualType(Context.LongDoubleTy)
300 << false << Context.getTargetInfo().getTriple().str();
301 // Argument type should be exact.
302 QualType ArgType = QualType(Context.LongDoubleTy);
303 if (BuiltinID == PPC::BI__builtin_ppc_maxfl ||
304 BuiltinID == PPC::BI__builtin_ppc_minfl)
305 ArgType = QualType(Context.DoubleTy);
306 else if (BuiltinID == PPC::BI__builtin_ppc_maxfs ||
307 BuiltinID == PPC::BI__builtin_ppc_minfs)
308 ArgType = QualType(Context.FloatTy);
309 for (unsigned I = 0, E = TheCall->getNumArgs(); I < E; ++I)
310 if (TheCall->getArg(I)->getType() != ArgType)
311 return Diag(TheCall->getBeginLoc(),
312 diag::err_typecheck_convert_incompatible)
313 << TheCall->getArg(I)->getType() << ArgType << 1 << 0 << 0;
314 return false;
315 }
316#define CUSTOM_BUILTIN(Name, Intr, Types, Acc, Feature) \
317 case PPC::BI__builtin_##Name: \
318 return BuiltinPPCMMACall(TheCall, BuiltinID, Types);
319#include "clang/Basic/BuiltinsPPC.def"
320 case PPC::BI__builtin_amo_lwat:
321 case PPC::BI__builtin_amo_ldat:
322 case PPC::BI__builtin_amo_lwat_s:
323 case PPC::BI__builtin_amo_ldat_s: {
324 llvm::APSInt Result;
325 if (SemaRef.BuiltinConstantArg(TheCall, 2, Result))
326 return true;
327 unsigned Val = Result.getZExtValue();
328
329 bool IsUnsigned = (BuiltinID == PPC::BI__builtin_amo_lwat ||
330 BuiltinID == PPC::BI__builtin_amo_ldat);
331
332 bool IsValid = IsUnsigned
333 ? llvm::is_contained({0u, 1u, 2u, 3u, 4u, 6u, 8u}, Val)
334 : llvm::is_contained({0u, 5u, 7u, 8u}, Val);
335
336 if (IsValid)
337 return false;
338
339 Expr *Arg = TheCall->getArg(2);
340 return SemaRef.Diag(Arg->getBeginLoc(), diag::err_argument_invalid_range)
341 << toString(Result, 10) << (IsUnsigned ? "0-4, 6" : "0, 5, 7") << "8"
342 << Arg->getSourceRange();
343 }
344 case PPC::BI__builtin_amo_lwat_cond:
345 case PPC::BI__builtin_amo_ldat_cond:
346 case PPC::BI__builtin_amo_lwat_cond_s:
347 case PPC::BI__builtin_amo_ldat_cond_s: {
348 llvm::APSInt Result;
349 if (SemaRef.BuiltinConstantArg(TheCall, 1, Result))
350 return true;
351 unsigned Val = Result.getZExtValue();
352 if (llvm::is_contained({24u, 25u, 28u}, Val))
353 return false;
354
355 Expr *Arg = TheCall->getArg(1);
356 return SemaRef.Diag(Arg->getBeginLoc(), diag::err_argument_invalid_range)
357 << toString(Result, 10) << "24, 25" << "28" << Arg->getSourceRange();
358 }
359 case PPC::BI__builtin_amo_stwat:
360 case PPC::BI__builtin_amo_stdat:
361 case PPC::BI__builtin_amo_stwat_s:
362 case PPC::BI__builtin_amo_stdat_s: {
363 llvm::APSInt Result;
364 if (SemaRef.BuiltinConstantArg(TheCall, 2, Result))
365 return true;
366 unsigned Val = Result.getZExtValue();
367
368 bool IsUnsigned = (BuiltinID == PPC::BI__builtin_amo_stwat ||
369 BuiltinID == PPC::BI__builtin_amo_stdat);
370
371 bool IsValid = IsUnsigned
372 ? llvm::is_contained({0u, 1u, 2u, 3u, 4u, 6u, 24u}, Val)
373 : llvm::is_contained({0u, 5u, 7u, 24u}, Val);
374
375 if (IsValid)
376 return false;
377
378 Expr *Arg = TheCall->getArg(2);
379 return SemaRef.Diag(Arg->getBeginLoc(), diag::err_argument_invalid_range)
380 << toString(Result, 10) << (IsUnsigned ? "0-4, 6" : "0, 5, 7")
381 << "24" << Arg->getSourceRange();
382 }
383 }
384 llvm_unreachable("must return from switch");
385}
386
387// Check if the given type is a non-pointer PPC MMA type. This function is used
388// in Sema to prevent invalid uses of restricted PPC MMA types.
390 ASTContext &Context = getASTContext();
391 if (Type->isPointerType() || Type->isArrayType())
392 return false;
393
394 QualType CoreType = Type.getCanonicalType().getUnqualifiedType();
395#define PPC_VECTOR_TYPE(Name, Id, Size) || CoreType == Context.Id##Ty
396 if (false
397#include "clang/Basic/PPCTypes.def"
398 ) {
399 Diag(TypeLoc, diag::err_ppc_invalid_use_mma_type);
400 return true;
401 }
402 return false;
403}
404
405/// DecodePPCMMATypeFromStr - This decodes one PPC MMA type descriptor from Str,
406/// advancing the pointer over the consumed characters. The decoded type is
407/// returned. If the decoded type represents a constant integer with a
408/// constraint on its value then Mask is set to that value. The type descriptors
409/// used in Str are specific to PPC MMA builtins and are documented in the file
410/// defining the PPC builtins.
411static QualType DecodePPCMMATypeFromStr(ASTContext &Context, const char *&Str,
412 unsigned &Mask) {
413 bool RequireICE = false;
415 switch (*Str++) {
416 case 'V':
417 return Context.getVectorType(Context.UnsignedCharTy, 16,
419 case 'i': {
420 char *End;
421 unsigned size = strtoul(Str, &End, 10);
422 assert(End != Str && "Missing constant parameter constraint");
423 Str = End;
424 Mask = size;
425 return Context.IntTy;
426 }
427 case 'W': {
428 char *End;
429 unsigned size = strtoul(Str, &End, 10);
430 assert(End != Str && "Missing PowerPC MMA type size");
431 Str = End;
433 switch (size) {
434#define PPC_VECTOR_TYPE(typeName, Id, size) \
435 case size: \
436 Type = Context.Id##Ty; \
437 break;
438#include "clang/Basic/PPCTypes.def"
439 default:
440 llvm_unreachable("Invalid PowerPC MMA vector type");
441 }
442 bool CheckVectorArgs = false;
443 while (!CheckVectorArgs) {
444 switch (*Str++) {
445 case '*':
446 Type = Context.getPointerType(Type);
447 break;
448 case 'C':
449 Type = Type.withConst();
450 break;
451 default:
452 CheckVectorArgs = true;
453 --Str;
454 break;
455 }
456 }
457 return Type;
458 }
459 default:
460 return Context.DecodeTypeStr(--Str, Context, Error, RequireICE, true);
461 }
462}
463
464bool SemaPPC::BuiltinPPCMMACall(CallExpr *TheCall, unsigned BuiltinID,
465 const char *TypeStr) {
466
467 assert((TypeStr[0] != '\0') &&
468 "Invalid types in PPC MMA builtin declaration");
469
470 ASTContext &Context = getASTContext();
471 unsigned Mask = 0;
472 unsigned ArgNum = 0;
473
474 // The first type in TypeStr is the type of the value returned by the
475 // builtin. So we first read that type and change the type of TheCall.
476 QualType type = DecodePPCMMATypeFromStr(Context, TypeStr, Mask);
477 TheCall->setType(type);
478
479 while (*TypeStr != '\0') {
480 Mask = 0;
481 QualType ExpectedType = DecodePPCMMATypeFromStr(Context, TypeStr, Mask);
482 if (ArgNum >= TheCall->getNumArgs()) {
483 ArgNum++;
484 break;
485 }
486
487 Expr *Arg = TheCall->getArg(ArgNum);
488 QualType PassedType = Arg->getType();
489 QualType StrippedRVType = PassedType.getCanonicalType();
490
491 // Strip Restrict/Volatile qualifiers.
492 if (StrippedRVType.isRestrictQualified() ||
493 StrippedRVType.isVolatileQualified())
494 StrippedRVType = StrippedRVType.getCanonicalType().getUnqualifiedType();
495
496 // The only case where the argument type and expected type are allowed to
497 // mismatch is if the argument type is a non-void pointer (or array) and
498 // expected type is a void pointer.
499 if (StrippedRVType != ExpectedType)
500 if (!(ExpectedType->isVoidPointerType() &&
501 (StrippedRVType->isPointerType() || StrippedRVType->isArrayType())))
502 return Diag(Arg->getBeginLoc(),
503 diag::err_typecheck_convert_incompatible)
504 << PassedType << ExpectedType << 1 << 0 << 0;
505
506 // If the value of the Mask is not 0, we have a constraint in the size of
507 // the integer argument so here we ensure the argument is a constant that
508 // is in the valid range.
509 if (Mask != 0 &&
510 SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, Mask, true))
511 return true;
512
513 ArgNum++;
514 }
515
516 // In case we exited early from the previous loop, there are other types to
517 // read from TypeStr. So we need to read them all to ensure we have the right
518 // number of arguments in TheCall and if it is not the case, to display a
519 // better error message.
520 while (*TypeStr != '\0') {
521 (void)DecodePPCMMATypeFromStr(Context, TypeStr, Mask);
522 ArgNum++;
523 }
524 if (SemaRef.checkArgCount(TheCall, ArgNum))
525 return true;
526
527 return false;
528}
529
531 unsigned ExpectedNumArgs = 3;
532 if (SemaRef.checkArgCount(TheCall, ExpectedNumArgs))
533 return true;
534
535 // Check the third argument is a compile time constant
536 if (!TheCall->getArg(2)->isIntegerConstantExpr(getASTContext()))
537 return Diag(TheCall->getBeginLoc(),
538 diag::err_vsx_builtin_nonconstant_argument)
539 << 3 /* argument index */ << TheCall->getDirectCallee()
540 << SourceRange(TheCall->getArg(2)->getBeginLoc(),
541 TheCall->getArg(2)->getEndLoc());
542
543 QualType Arg1Ty = TheCall->getArg(0)->getType();
544 QualType Arg2Ty = TheCall->getArg(1)->getType();
545
546 // Check the type of argument 1 and argument 2 are vectors.
547 SourceLocation BuiltinLoc = TheCall->getBeginLoc();
548 if ((!Arg1Ty->isVectorType() && !Arg1Ty->isDependentType()) ||
549 (!Arg2Ty->isVectorType() && !Arg2Ty->isDependentType())) {
550 return Diag(BuiltinLoc, diag::err_vec_builtin_non_vector)
551 << TheCall->getDirectCallee() << /*isMorethantwoArgs*/ false
552 << SourceRange(TheCall->getArg(0)->getBeginLoc(),
553 TheCall->getArg(1)->getEndLoc());
554 }
555
556 // Check the first two arguments are the same type.
557 if (!getASTContext().hasSameUnqualifiedType(Arg1Ty, Arg2Ty)) {
558 return Diag(BuiltinLoc, diag::err_vec_builtin_incompatible_vector)
559 << TheCall->getDirectCallee() << /*isMorethantwoArgs*/ false
560 << SourceRange(TheCall->getArg(0)->getBeginLoc(),
561 TheCall->getArg(1)->getEndLoc());
562 }
563
564 // When default clang type checking is turned off and the customized type
565 // checking is used, the returning type of the function must be explicitly
566 // set. Otherwise it is _Bool by default.
567 TheCall->setType(Arg1Ty);
568
569 return false;
570}
571
572} // 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
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
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:3160
A (possibly-)qualified type.
Definition TypeBase.h:937
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
Definition TypeBase.h:8433
bool isRestrictQualified() const
Determine whether this type is restrict-qualified.
Definition TypeBase.h:8427
QualType getCanonicalType() const
Definition TypeBase.h:8401
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition TypeBase.h:8443
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 CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
Definition SemaPPC.cpp:107
void checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg)
Definition SemaPPC.cpp:30
SemaPPC(Sema &S)
Definition SemaPPC.cpp:28
bool BuiltinPPCMMACall(CallExpr *TheCall, unsigned BuiltinID, const char *TypeDesc)
BuiltinPPCMMACall - Check the call to a PPC MMA builtin for validity.
Definition SemaPPC.cpp:464
bool BuiltinVSX(CallExpr *TheCall)
Definition SemaPPC.cpp:530
bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc)
Definition SemaPPC.cpp:389
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:868
Encodes a location in the source.
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:226
unsigned getTypeWidth(IntType T) const
Return the width (in bits) of the specified integer type enum.
IntType getIntPtrType() const
Definition TargetInfo.h:414
const llvm::fltSemantics & getLongDoubleFormat() const
Definition TargetInfo.h:809
Base wrapper for a particular "section" of type source info.
Definition TypeLoc.h:59
The base class of the type hierarchy.
Definition TypeBase.h:1839
bool isArrayType() const
Definition TypeBase.h:8685
bool isPointerType() const
Definition TypeBase.h:8586
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition TypeBase.h:8996
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition TypeBase.h:2790
bool isVectorType() const
Definition TypeBase.h:8725
Defines the clang::TargetInfo interface.
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:56
@ 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:411
@ AltiVecVector
is AltiVec vector
Definition TypeBase.h:4147