20#include "llvm/Support/AArch64MemoryHints.h"
31 if (BuiltinID == AArch64::BI__builtin_arm_irg) {
32 if (
SemaRef.checkArgCount(TheCall, 2))
42 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_must_be_pointer)
47 Context, Context.getIntTypeForBitwidth(64,
false),
50 SemaRef.PerformCopyInitialization(Entity,
61 if (BuiltinID == AArch64::BI__builtin_arm_addg) {
62 if (
SemaRef.checkArgCount(TheCall, 2))
71 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_must_be_pointer)
79 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 15);
82 if (BuiltinID == AArch64::BI__builtin_arm_gmi) {
83 if (
SemaRef.checkArgCount(TheCall, 2))
93 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_must_be_pointer)
98 Context, Context.getIntTypeForBitwidth(64,
false),
101 SemaRef.PerformCopyInitialization(Entity,
110 if (BuiltinID == AArch64::BI__builtin_arm_ldg ||
111 BuiltinID == AArch64::BI__builtin_arm_stg) {
112 if (
SemaRef.checkArgCount(TheCall, 1))
121 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_must_be_pointer)
126 if (BuiltinID == AArch64::BI__builtin_arm_ldg)
127 TheCall->
setType(FirstArgType);
131 if (BuiltinID == AArch64::BI__builtin_arm_subp) {
144 auto isNull = [&](
Expr *E) ->
bool {
145 return E->isNullPointerConstant(Context,
151 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_null_or_pointer)
155 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_null_or_pointer)
163 if (!Context.typesAreCompatible(
164 Context.getCanonicalType(pointeeA).getUnqualifiedType(),
165 Context.getCanonicalType(pointeeB).getUnqualifiedType())) {
167 diag::err_typecheck_sub_ptr_compatible)
180 SemaRef.ImpCastExprToType(ArgExprA.
get(), ArgTypeB, CK_NullToPointer);
184 SemaRef.ImpCastExprToType(ArgExprB.
get(), ArgTypeA, CK_NullToPointer);
190 assert(
false &&
"Unhandled ARM MTE intrinsic");
197 int ArgNum,
unsigned ExpectedFieldNum,
199 bool IsARMBuiltin = BuiltinID == ARM::BI__builtin_arm_rsr64 ||
200 BuiltinID == ARM::BI__builtin_arm_wsr64 ||
201 BuiltinID == ARM::BI__builtin_arm_rsr ||
202 BuiltinID == ARM::BI__builtin_arm_rsrp ||
203 BuiltinID == ARM::BI__builtin_arm_wsr ||
204 BuiltinID == ARM::BI__builtin_arm_wsrp;
205 bool IsAArch64Builtin = BuiltinID == AArch64::BI__builtin_arm_rsr64 ||
206 BuiltinID == AArch64::BI__builtin_arm_wsr64 ||
207 BuiltinID == AArch64::BI__builtin_arm_rsr128 ||
208 BuiltinID == AArch64::BI__builtin_arm_wsr128 ||
209 BuiltinID == AArch64::BI__builtin_arm_rsr ||
210 BuiltinID == AArch64::BI__builtin_arm_rsrp ||
211 BuiltinID == AArch64::BI__builtin_arm_wsr ||
212 BuiltinID == AArch64::BI__builtin_arm_wsrp;
213 assert((IsARMBuiltin || IsAArch64Builtin) &&
"Unexpected ARM builtin.");
228 Reg.split(Fields,
":");
230 if (Fields.size() != ExpectedFieldNum && !(AllowName && Fields.size() == 1))
238 if (Fields.size() > 1) {
239 bool FiveFields = Fields.size() == 5;
241 bool ValidString =
true;
243 ValidString &= Fields[0].starts_with_insensitive(
"cp") ||
244 Fields[0].starts_with_insensitive(
"p");
246 Fields[0] = Fields[0].drop_front(
247 Fields[0].starts_with_insensitive(
"cp") ? 2 : 1);
249 ValidString &= Fields[2].starts_with_insensitive(
"c");
251 Fields[2] = Fields[2].drop_front(1);
254 ValidString &= Fields[3].starts_with_insensitive(
"c");
256 Fields[3] = Fields[3].drop_front(1);
262 FieldBitWidths.append({IsAArch64Builtin ? 2 : 4, 3, 4, 4, 3});
264 FieldBitWidths.append({4, 3, 4});
266 for (
unsigned i = 0; i < Fields.size(); ++i) {
268 ValidString &= !Fields[i].getAsInteger(10, IntField);
269 ValidString &= (IntField >= 0 && IntField < (1 << FieldBitWidths[i]));
275 }
else if (IsAArch64Builtin && Fields.size() == 1) {
283 if (BuiltinID == AArch64::BI__builtin_arm_rsr128 ||
284 BuiltinID == AArch64::BI__builtin_arm_wsr128)
289 auto MaxLimit = llvm::StringSwitch<std::optional<unsigned>>(Reg)
290 .CaseLower(
"spsel", 15)
291 .CaseLower(
"daifclr", 15)
292 .CaseLower(
"daifset", 15)
293 .CaseLower(
"pan", 15)
294 .CaseLower(
"uao", 15)
295 .CaseLower(
"dit", 15)
296 .CaseLower(
"ssbs", 15)
297 .CaseLower(
"tco", 15)
298 .CaseLower(
"allint", 1)
300 .Default(std::nullopt);
320 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, *MaxLimit);
328 if (
SemaRef.checkArgCount(TheCall, 4))
335 SemaRef.DefaultFunctionArrayLvalueConversion(TheCall->
getArg(0));
336 if (PtrArgRes.isInvalid())
338 auto *PtrArg = PtrArgRes.get();
339 auto *PtrTy = PtrArg->getType()->getAs<
PointerType>();
342 diag::err_atomic_hint_builtin_must_be_pointer)
343 << PtrArg->getType() << 0 << PtrArg->getSourceRange();
344 TheCall->
setArg(0, PtrArg);
349 diag::err_atomic_op_needs_non_const_pointer)
350 << PtrQT << PtrArg->getSourceRange();
356 diag::err_atomic_op_needs_atomic_int_or_fp)
357 << 0 << PtrQT << PtrArg->getSourceRange();
361 diag::err_atomic_builtin_bit_int_prohibit)
362 << PtrQT << PtrArg->getSourceRange();
364 unsigned TySize = Context.getTypeSize(PtrQT);
365 if (TySize != 8 && TySize != 16 && TySize != 32 && TySize != 64)
366 return Diag(TheCall->
getBeginLoc(), diag::err_atomic_op_hint_data_size)
367 << PtrArg->getSourceRange();
372 SemaRef.DefaultFunctionArrayLvalueConversion(TheCall->
getArg(1));
373 if (DataArgRes.isInvalid())
375 auto *DataArg = DataArgRes.get();
378 TheCall->
setArg(1, DataArg);
382 diag::err_typecheck_call_different_arg_types)
387 SemaRef.DefaultFunctionArrayLvalueConversion(TheCall->
getArg(2));
388 if (MemOrdArg.isInvalid())
390 auto *MemOrd = MemOrdArg.get();
391 if (
SemaRef.convertArgumentToType(MemOrd, Context.IntTy))
393 TheCall->
setArg(2, MemOrd);
395 if (!MemOrd->isValueDependent()) {
396 std::optional<llvm::APSInt> MemOrdAP =
397 MemOrd->getIntegerConstantExpr(Context);
400 diag::err_atomic_hint_has_invalid_memory_order)
401 << MemOrd->getType() << MemOrd->getSourceRange();
403 unsigned Ordering = MemOrdAP->getZExtValue();
404 if (!llvm::isValidAtomicOrderingCABI(Ordering))
406 diag::err_atomic_hint_has_invalid_memory_order)
407 << *MemOrdAP << MemOrd->getSourceRange();
409 auto AtomicOrdering =
static_cast<llvm::AtomicOrderingCABI
>(Ordering);
410 if (AtomicOrdering != llvm::AtomicOrderingCABI::relaxed &&
411 AtomicOrdering != llvm::AtomicOrderingCABI::release &&
412 AtomicOrdering != llvm::AtomicOrderingCABI::seq_cst)
414 diag::err_atomic_hint_has_invalid_memory_order)
415 << *MemOrdAP << MemOrd->getSourceRange();
421 SemaRef.DefaultFunctionArrayLvalueConversion(TheCall->
getArg(3));
422 if (HintArg.isInvalid())
424 auto Hint = HintArg.get();
425 if (
SemaRef.convertArgumentToType(Hint, Context.IntTy))
429 if (!Hint->isValueDependent()) {
430 std::optional<llvm::APSInt> HintAP = Hint->getIntegerConstantExpr(Context);
433 diag::err_atomic_hint_has_invalid_hint_type)
434 << Hint->getType() << Hint->getSourceRange();
436 if (llvm::toAArch64MemoryHint(HintAP->getZExtValue()) ==
437 llvm::AArch64MemoryHint::NONE) {
438 Diag(TheCall->
getBeginLoc(), diag::warn_atomic_hint_has_invalid_hint_type)
439 << *HintAP << Hint->getSourceRange();
450 bool IsPolyUnsigned,
bool IsInt64Long) {
453 return Flags.
isUnsigned() ? Context.UnsignedCharTy : Context.SignedCharTy;
455 return Flags.
isUnsigned() ? Context.UnsignedShortTy : Context.ShortTy;
457 return Flags.
isUnsigned() ? Context.UnsignedIntTy : Context.IntTy;
460 return Flags.
isUnsigned() ? Context.UnsignedLongTy : Context.LongTy;
462 return Flags.
isUnsigned() ? Context.UnsignedLongLongTy
463 : Context.LongLongTy;
465 return IsPolyUnsigned ? Context.UnsignedCharTy : Context.SignedCharTy;
467 return IsPolyUnsigned ? Context.UnsignedShortTy : Context.ShortTy;
470 return Context.UnsignedLongTy;
472 return Context.UnsignedLongLongTy;
476 return Context.HalfTy;
478 return Context.FloatTy;
480 return Context.DoubleTy;
482 return Context.BFloat16Ty;
484 return Context.MFloat8Ty;
486 llvm_unreachable(
"Invalid NeonTypeFlag!");
504 unsigned ArgIdx,
unsigned EltBitWidth,
505 unsigned ContainerBitWidth) {
508 auto CheckImmediateInSet = [&](std::initializer_list<int64_t>
Set,
509 int ErrDiag) ->
bool {
517 if (
SemaRef.BuiltinConstantArg(TheCall, ArgIdx, Imm))
520 if (!llvm::is_contained(
Set, Imm.getSExtValue()))
526 case ImmCheckType::ImmCheck0_31:
527 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 31))
530 case ImmCheckType::ImmCheck0_13:
531 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 13))
534 case ImmCheckType::ImmCheck0_63:
535 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 63))
538 case ImmCheckType::ImmCheck1_16:
539 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 16))
542 case ImmCheckType::ImmCheck0_7:
543 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 7))
546 case ImmCheckType::ImmCheck1_1:
547 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 1))
550 case ImmCheckType::ImmCheck1_3:
551 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 3))
554 case ImmCheckType::ImmCheck1_7:
555 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 7))
558 case ImmCheckType::ImmCheckExtract:
559 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0,
560 (2048 / EltBitWidth) - 1))
563 case ImmCheckType::ImmCheckCvt:
564 case ImmCheckType::ImmCheckShiftRight:
565 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, EltBitWidth))
568 case ImmCheckType::ImmCheckShiftRightNarrow:
569 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, EltBitWidth / 2))
572 case ImmCheckType::ImmCheckShiftLeft:
573 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, EltBitWidth - 1))
576 case ImmCheckType::ImmCheckShiftLeftLong:
577 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, (EltBitWidth / 2)))
580 case ImmCheckType::ImmCheckLaneIndex:
581 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0,
582 (ContainerBitWidth / EltBitWidth) - 1))
585 case ImmCheckType::ImmCheckLaneIndexCompRotate:
586 if (
SemaRef.BuiltinConstantArgRange(
587 TheCall, ArgIdx, 0, (ContainerBitWidth / (2 * EltBitWidth)) - 1))
590 case ImmCheckType::ImmCheckLaneIndexDot:
591 if (
SemaRef.BuiltinConstantArgRange(
592 TheCall, ArgIdx, 0, (ContainerBitWidth / (4 * EltBitWidth)) - 1))
595 case ImmCheckType::ImmCheckComplexRot90_270:
596 if (CheckImmediateInSet({90, 270}, diag::err_rotation_argument_to_cadd))
599 case ImmCheckType::ImmCheckComplexRotAll90:
600 if (CheckImmediateInSet({0, 90, 180, 270},
601 diag::err_rotation_argument_to_cmla))
604 case ImmCheckType::ImmCheck0_1:
605 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 1))
608 case ImmCheckType::ImmCheck0_2:
609 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 2))
612 case ImmCheckType::ImmCheck0_3:
613 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 3))
616 case ImmCheckType::ImmCheck0_0:
617 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 0))
620 case ImmCheckType::ImmCheck0_15:
621 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 15))
624 case ImmCheckType::ImmCheck0_255:
625 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 255))
628 case ImmCheckType::ImmCheck1_32:
629 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 32))
632 case ImmCheckType::ImmCheck1_64:
633 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 64))
636 case ImmCheckType::ImmCheck2_4_Mul2:
637 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 2, 4) ||
638 SemaRef.BuiltinConstantArgMultiple(TheCall, ArgIdx, 2))
649 bool HasError =
false;
651 for (
const auto &I : ImmChecks) {
652 auto [ArgIdx, CheckTy, ElementBitWidth, VecBitWidth] = I;
654 if (OverloadType >= 0)
666 bool HasError =
false;
668 for (
const auto &I : ImmChecks) {
669 auto [ArgIdx, CheckTy, ElementBitWidth] = I;
678 if (FD->
hasAttr<ArmLocallyStreamingAttr>())
682 if (FPT->getAArch64SMEAttributes() &
685 if (FPT->getAArch64SMEAttributes() &
696 unsigned BuiltinID) {
704 llvm::StringMap<bool> CallerFeatures;
711 const auto FindTopLevelPipe = [](
const char *S) {
713 unsigned I = 0, E = strlen(S);
715 if (S[I] ==
'|' && Depth == 0)
719 else if (S[I] ==
')')
725 const char *RequiredFeatures =
727 unsigned PipeIdx = FindTopLevelPipe(RequiredFeatures);
728 assert(PipeIdx != 0 && PipeIdx != strlen(RequiredFeatures) &&
729 "Expected feature string of the form 'SVE-EXPR|SME-EXPR'");
730 StringRef NonStreamingBuiltinGuard = StringRef(RequiredFeatures, PipeIdx);
731 StringRef StreamingBuiltinGuard = StringRef(RequiredFeatures + PipeIdx + 1);
734 NonStreamingBuiltinGuard, CallerFeatures);
736 StreamingBuiltinGuard, CallerFeatures);
738 if (SatisfiesSVE && SatisfiesSME)
741 else if (SatisfiesSVE)
743 else if (SatisfiesSME)
752 S.
Diag(TheCall->
getBeginLoc(), diag::err_attribute_arm_sm_incompat_builtin)
756 S.
Diag(TheCall->
getBeginLoc(), diag::err_attribute_arm_sm_incompat_builtin)
768#define GET_SME_BUILTIN_GET_STATE
769#include "clang/Basic/arm_sme_builtins_za_state.inc"
770#undef GET_SME_BUILTIN_GET_STATE
777 SemaRef.getCurFunctionDecl(
true)) {
781#define GET_SME_STREAMING_ATTRS
782#include "clang/Basic/arm_sme_streaming_attrs.inc"
783#undef GET_SME_STREAMING_ATTRS
792 diag::err_attribute_arm_za_builtin_no_za_state)
799 diag::err_attribute_arm_zt0_builtin_no_zt0_state)
811#define GET_SME_IMMEDIATE_CHECK
812#include "clang/Basic/arm_sme_sema_rangechecks.inc"
813#undef GET_SME_IMMEDIATE_CHECK
822 SemaRef.getCurFunctionDecl(
true)) {
826#define GET_SVE_STREAMING_ATTRS
827#include "clang/Basic/arm_sve_streaming_attrs.inc"
828#undef GET_SVE_STREAMING_ATTRS
840#define GET_SVE_IMMEDIATE_CHECK
841#include "clang/Basic/arm_sve_sema_rangechecks.inc"
842#undef GET_SVE_IMMEDIATE_CHECK
852 SemaRef.getCurFunctionDecl(
true)) {
858#define GET_NEON_STREAMING_COMPAT_FLAG
859#include "clang/Basic/arm_neon.inc"
860#undef GET_NEON_STREAMING_COMPAT_FLAG
871 bool HasConstPtr =
false;
873#define GET_NEON_OVERLOAD_CHECK
874#include "clang/Basic/arm_fp16.inc"
875#include "clang/Basic/arm_neon.inc"
876#undef GET_NEON_OVERLOAD_CHECK
888 TV =
Result.getLimitedValue(64);
889 if ((TV > 63) || (mask & (1ULL << TV)) == 0)
894 if (PtrArgNum >= 0) {
898 Arg = ICE->getSubExpr();
903 bool IsPolyUnsigned =
Arch == llvm::Triple::aarch64 ||
904 Arch == llvm::Triple::aarch64_32 ||
905 Arch == llvm::Triple::aarch64_be;
908 IsPolyUnsigned, IsInt64Long);
913 ConvTy =
SemaRef.CheckSingleAssignmentConstraints(LHSTy, RHS);
928#define GET_NEON_IMMEDIATE_CHECK
929#include "clang/Basic/arm_fp16.inc"
930#include "clang/Basic/arm_neon.inc"
931#undef GET_NEON_IMMEDIATE_CHECK
942#include "clang/Basic/arm_mve_builtin_sema.inc"
953#include "clang/Basic/arm_cde_builtin_sema.inc"
963 const Expr *CoprocArg,
966 if (
SemaRef.isConstantEvaluatedContext())
974 int64_t CoprocNo = CoprocNoAP.getExtValue();
975 assert(CoprocNo >= 0 &&
"Coprocessor immediate must be non-negative");
978 bool IsCDECoproc = CoprocNo <= 7 && (CDECoprocMask & (1 << CoprocNo));
980 if (IsCDECoproc != WantCDE)
990 assert((BuiltinID == ARM::BI__builtin_arm_ldrex ||
991 BuiltinID == ARM::BI__builtin_arm_ldrexd ||
992 BuiltinID == ARM::BI__builtin_arm_ldaex ||
993 BuiltinID == ARM::BI__builtin_arm_strex ||
994 BuiltinID == ARM::BI__builtin_arm_strexd ||
995 BuiltinID == ARM::BI__builtin_arm_stlex ||
996 BuiltinID == AArch64::BI__builtin_arm_ldrex ||
997 BuiltinID == AArch64::BI__builtin_arm_ldaex ||
998 BuiltinID == AArch64::BI__builtin_arm_strex ||
999 BuiltinID == AArch64::BI__builtin_arm_stlex) &&
1000 "unexpected ARM builtin");
1001 bool IsLdrex = BuiltinID == ARM::BI__builtin_arm_ldrex ||
1002 BuiltinID == ARM::BI__builtin_arm_ldrexd ||
1003 BuiltinID == ARM::BI__builtin_arm_ldaex ||
1004 BuiltinID == AArch64::BI__builtin_arm_ldrex ||
1005 BuiltinID == AArch64::BI__builtin_arm_ldaex;
1006 bool IsDoubleWord = BuiltinID == ARM::BI__builtin_arm_ldrexd ||
1007 BuiltinID == ARM::BI__builtin_arm_strexd;
1014 if (
SemaRef.checkArgCount(TheCall, IsLdrex ? 1 : 2))
1021 Expr *PointerArg = TheCall->
getArg(IsLdrex ? 0 : 1);
1023 SemaRef.DefaultFunctionArrayLvalueConversion(PointerArg);
1026 PointerArg = PointerArgRes.
get();
1046 CastNeeded = CK_BitCast;
1047 Diag(DRE->
getBeginLoc(), diag::ext_typecheck_convert_discards_qualifiers)
1048 << PointerArg->
getType() << Context.getPointerType(AddrType)
1053 AddrType = Context.getPointerType(AddrType);
1054 PointerArgRes =
SemaRef.ImpCastExprToType(PointerArg, AddrType, CastNeeded);
1057 PointerArg = PointerArgRes.
get();
1059 TheCall->
setArg(IsLdrex ? 0 : 1, PointerArg);
1064 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intfltptr)
1073 unsigned Bits = Context.getTypeSize(ValType);
1080 (llvm::isPowerOf2_64(Bits)) && Bits >= 8 && (Mask & (Bits / 8));
1090 diag::err_atomic_exclusive_builtin_pointer_size)
1092 bool Started =
false;
1093 for (
unsigned Size = 1; Size <= 8; Size <<= 1) {
1100 if (!(Mask & Size)) {
1119 bool EmitDoubleWordDiagnostic =
1122 diag::err_atomic_exclusive_builtin_pointer_size_none)
1123 << (EmitDoubleWordDiagnostic ? 1 : 0)
1151 Context, ValType,
false);
1159 TheCall->
setType(Context.IntTy);
1164 int64_t Low, int64_t High) {
1177 return S.
Diag(
Call->getBeginLoc(), diag::warn_argument_invalid_range)
1186 if (BuiltinID == ARM::BI__builtin_arm_ldrex ||
1187 BuiltinID == ARM::BI__builtin_arm_ldrexd ||
1188 BuiltinID == ARM::BI__builtin_arm_ldaex ||
1189 BuiltinID == ARM::BI__builtin_arm_strex ||
1190 BuiltinID == ARM::BI__builtin_arm_strexd ||
1191 BuiltinID == ARM::BI__builtin_arm_stlex) {
1195 if (BuiltinID == ARM::BI__builtin_arm_prefetch) {
1196 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) ||
1197 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 1);
1200 if (BuiltinID == ARM::BI__builtin_arm_rsr64 ||
1201 BuiltinID == ARM::BI__builtin_arm_wsr64)
1204 if (BuiltinID == ARM::BI__builtin_arm_rsr ||
1205 BuiltinID == ARM::BI__builtin_arm_rsrp ||
1206 BuiltinID == ARM::BI__builtin_arm_wsr ||
1207 BuiltinID == ARM::BI__builtin_arm_wsrp)
1219 switch (BuiltinID) {
1222 case ARM::BI__builtin_arm_ssat:
1223 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 1, 32);
1224 case ARM::BI__builtin_arm_usat:
1225 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31);
1226 case ARM::BI__builtin_arm_ssat16:
1227 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 1, 16);
1228 case ARM::BI__builtin_arm_usat16:
1229 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 15);
1230 case ARM::BI__builtin_arm_vcvtr_f:
1231 case ARM::BI__builtin_arm_vcvtr_d:
1232 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1);
1233 case ARM::BI__builtin_arm_dmb:
1235 case ARM::BI__builtin_arm_dsb:
1237 case ARM::BI__builtin_arm_isb:
1239 case ARM::BI__builtin_arm_dbg:
1240 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 15);
1241 case ARM::BI__builtin_arm_cdp:
1242 case ARM::BI__builtin_arm_cdp2:
1243 case ARM::BI__builtin_arm_mcr:
1244 case ARM::BI__builtin_arm_mcr2:
1245 case ARM::BI__builtin_arm_mrc:
1246 case ARM::BI__builtin_arm_mrc2:
1247 case ARM::BI__builtin_arm_mcrr:
1248 case ARM::BI__builtin_arm_mcrr2:
1249 case ARM::BI__builtin_arm_mrrc:
1250 case ARM::BI__builtin_arm_mrrc2:
1251 case ARM::BI__builtin_arm_ldc:
1252 case ARM::BI__builtin_arm_ldcl:
1253 case ARM::BI__builtin_arm_ldc2:
1254 case ARM::BI__builtin_arm_ldc2l:
1255 case ARM::BI__builtin_arm_stc:
1256 case ARM::BI__builtin_arm_stcl:
1257 case ARM::BI__builtin_arm_stc2:
1258 case ARM::BI__builtin_arm_stc2l:
1259 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 15) ||
1268 if (BuiltinID == AArch64::BI__builtin_arm_ldrex ||
1269 BuiltinID == AArch64::BI__builtin_arm_ldaex ||
1270 BuiltinID == AArch64::BI__builtin_arm_strex ||
1271 BuiltinID == AArch64::BI__builtin_arm_stlex) {
1275 if (BuiltinID == AArch64::BI__builtin_arm_prefetch) {
1276 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) ||
1277 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3) ||
1278 SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 1) ||
1279 SemaRef.BuiltinConstantArgRange(TheCall, 4, 0, 1);
1282 if (BuiltinID == AArch64::BI__builtin_arm_range_prefetch_x) {
1283 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) ||
1284 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 1) ||
1285 SemaRef.BuiltinConstantArgRange(TheCall, 3, -2097152, 2097151) ||
1286 SemaRef.BuiltinConstantArgRange(TheCall, 4, 1, 65536) ||
1287 SemaRef.BuiltinConstantArgRange(TheCall, 5, -2097152, 2097151);
1290 if (BuiltinID == AArch64::BI__builtin_arm_range_prefetch) {
1291 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) ||
1292 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 1);
1295 if (BuiltinID == AArch64::BI__builtin_arm_rsr64 ||
1296 BuiltinID == AArch64::BI__builtin_arm_wsr64 ||
1297 BuiltinID == AArch64::BI__builtin_arm_rsr128 ||
1298 BuiltinID == AArch64::BI__builtin_arm_wsr128)
1302 if (BuiltinID == AArch64::BI__builtin_arm_irg ||
1303 BuiltinID == AArch64::BI__builtin_arm_addg ||
1304 BuiltinID == AArch64::BI__builtin_arm_gmi ||
1305 BuiltinID == AArch64::BI__builtin_arm_ldg ||
1306 BuiltinID == AArch64::BI__builtin_arm_stg ||
1307 BuiltinID == AArch64::BI__builtin_arm_subp) {
1311 if (BuiltinID == AArch64::BI__builtin_arm_rsr ||
1312 BuiltinID == AArch64::BI__builtin_arm_rsrp ||
1313 BuiltinID == AArch64::BI__builtin_arm_wsr ||
1314 BuiltinID == AArch64::BI__builtin_arm_wsrp)
1317 if (BuiltinID == AArch64::BI__builtin_arm_atomic_store_with_hint)
1325 if (BuiltinID == AArch64::BI_ReadStatusReg ||
1326 BuiltinID == AArch64::BI_WriteStatusReg)
1327 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 0x7fff);
1329 if (BuiltinID == AArch64::BI__sys)
1330 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 0x3fff);
1332 if (BuiltinID == AArch64::BI__getReg || BuiltinID == AArch64::BI__setReg ||
1333 BuiltinID == AArch64::BI__getRegFp || BuiltinID == AArch64::BI__setRegFp)
1334 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 31);
1336 if (BuiltinID == AArch64::BI__prefetch2)
1337 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31);
1339 if (BuiltinID == AArch64::BI__break)
1340 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 0xffff);
1342 if (BuiltinID == AArch64::BI__hlt)
1343 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 0xffff);
1345 if (BuiltinID == AArch64::BI__hvc || BuiltinID == AArch64::BI__svc) {
1348 if (
SemaRef.checkArgCountAtMost(TheCall, 5) ||
1349 SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 0xffff))
1352 for (
unsigned I = 1, N = TheCall->
getNumArgs(); I < N; ++I) {
1358 diag::err_aarch64_svc_hvc_invalid_arg_type)
1373 if (BuiltinID == AArch64::BI__arm_set_fpm_lscale)
1376 if (BuiltinID == AArch64::BI__arm_set_fpm_nscale)
1379 if (BuiltinID == AArch64::BI__arm_set_fpm_lscale2)
1384 unsigned i = 0, l = 0, u = 0;
1385 switch (BuiltinID) {
1386 default:
return false;
1387 case AArch64::BI__builtin_arm_dmb:
1388 case AArch64::BI__dmb:
1389 case AArch64::BI__builtin_arm_dsb:
1390 case AArch64::BI__dsb:
1391 case AArch64::BI__builtin_arm_isb:
1392 case AArch64::BI__isb:
1398 return SemaRef.BuiltinConstantArgRange(TheCall, i, l, u + l);
1402struct IntrinToName {
1411 const char *IntrinNames) {
1412 AliasName.consume_front(
"__arm_");
1413 const IntrinToName *It =
1414 llvm::lower_bound(Map, BuiltinID, [](
const IntrinToName &L,
unsigned Id) {
1417 if (It == Map.end() || It->Id != BuiltinID)
1419 StringRef FullName(&IntrinNames[It->FullName]);
1420 if (AliasName == FullName)
1422 if (It->ShortName == -1)
1424 StringRef ShortName(&IntrinNames[It->ShortName]);
1425 return AliasName == ShortName;
1429#include "clang/Basic/arm_mve_builtin_aliases.inc"
1437#include "clang/Basic/arm_cde_builtin_aliases.inc"
1458 Diag(AL.
getLoc(), diag::err_attribute_argument_n_type)
1467 bool IsAArch64 = Context.getTargetInfo().getTriple().isAArch64();
1472 Diag(AL.
getLoc(), diag::err_attribute_arm_builtin_alias);
1476 D->
addAttr(::new (Context) ArmBuiltinAliasAttr(Context, AL, Ident));
1482 auto CheckForIncompatibleAttr =
1484 StringRef IncompatibleStateName) {
1485 if (CurrentState == IncompatibleState) {
1486 S.
Diag(AL.
getLoc(), diag::err_attributes_are_not_compatible)
1487 << (std::string(
"'__arm_new(\"") + StateName.str() +
"\")'")
1488 << (std::string(
"'") + IncompatibleStateName.str() +
"(\"" +
1489 StateName.str() +
"\")'")
1504 Diag(AL.
getLoc(), diag::err_missing_arm_state) << AL;
1509 std::vector<StringRef> NewState;
1510 if (
const auto *ExistingAttr = D->
getAttr<ArmNewAttr>()) {
1511 for (StringRef S : ExistingAttr->newArgs())
1512 NewState.push_back(S);
1516 bool HasZT0 =
false;
1517 for (
unsigned I = 0, E = AL.
getNumArgs(); I != E; ++I) {
1518 StringRef StateName;
1520 if (!
SemaRef.checkStringLiteralArgumentAttr(AL, I, StateName, &LiteralLoc))
1523 if (StateName ==
"za")
1525 else if (StateName ==
"zt0")
1528 Diag(LiteralLoc, diag::err_unknown_arm_state) << StateName;
1533 if (!llvm::is_contained(NewState, StateName))
1534 NewState.push_back(StateName);
1557 Diag(AL.
getLoc(), diag::err_attribute_not_clinkage) << AL;
1562 if (!FD->isExternallyVisible()) {
1563 Diag(AL.
getLoc(), diag::warn_attribute_cmse_entry_static);
1573 Diag(AL.
getLoc(), diag::err_attribute_too_many_arguments) << AL << 1;
1582 else if (!
SemaRef.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
1585 ARMInterruptAttr::InterruptType Kind;
1586 if (!ARMInterruptAttr::ConvertStrToInterruptType(Str, Kind)) {
1587 Diag(AL.
getLoc(), diag::warn_attribute_type_not_supported)
1588 << AL << Str << ArgLoc;
1592 if (!D->
hasAttr<ARMSaveFPAttr>()) {
1607 SemaRef.ARM().handleInterruptAttr(D, AL);
1610 if (!D->
hasAttr<ARMInterruptAttr>()) {
1616 bool VFP =
SemaRef.Context.getTargetInfo().hasFeature(
"vfp");
1629 bool UsesSM = FD->
hasAttr<ArmLocallyStreamingAttr>();
1630 bool UsesZA =
Attr &&
Attr->isNewZA();
1631 bool UsesZT0 =
Attr &&
Attr->isNewZT0();
1633 if (UsesZA || UsesZT0) {
1641 if (FD->
hasAttr<ArmLocallyStreamingAttr>()) {
1644 diag::warn_sme_locally_streaming_has_vl_args_returns)
1647 return P->getOriginalType()->isSizelessVectorType();
1650 diag::warn_sme_locally_streaming_has_vl_args_returns)
1663 if (UsesSM || UsesZA) {
1664 llvm::StringMap<bool> FeatureMap;
1665 Context.getFunctionFeatureMap(FeatureMap, FD);
1666 if (!FeatureMap.contains(
"sme")) {
1669 diag::err_sme_definition_using_sm_in_non_sme_target);
1672 diag::err_sme_definition_using_za_in_non_sme_target);
1676 llvm::StringMap<bool> FeatureMap;
1677 Context.getFunctionFeatureMap(FeatureMap, FD);
1678 if (!FeatureMap.contains(
"sme2")) {
1680 diag::err_sme_definition_using_zt0_in_non_sme2_target);
1689 uint64_t VScale = IsStreaming ? Context.getLangOpts().VScaleStreamingMin
1690 : Context.getLangOpts().VScaleMin;
1691 if (Ty->
getKind() == BuiltinType::SveBool ||
1692 Ty->
getKind() == BuiltinType::SveCount)
1693 return (VScale * 128) / Context.getCharWidth();
1694 return VScale * 128;
1698 bool IsStreaming =
false;
1702 SemaRef.getCurFunctionDecl(
true)) {
1705 if (
T->getAArch64SMEAttributes() &
1722 return BT->getKind() == BuiltinType::SveBool;
1724 return VT->getElementType().getCanonicalType() ==
1726 BT->getKind() != BuiltinType::SveBool;
1728 return Context.getTypeSize(SecondType) ==
1730 Context.hasSameType(
1731 VT->getElementType(),
1732 Context.getBuiltinVectorTypeInfo(BT).ElementType);
1738 return IsValidCast(FirstType, SecondType) ||
1739 IsValidCast(SecondType, FirstType);
1744 bool IsStreaming =
false;
1748 SemaRef.getCurFunctionDecl(
true)) {
1751 if (
T->getAArch64SMEAttributes() &
1774 if (BT->getKind() == BuiltinType::SveBool &&
1784 Context.getTypeSize(SecondType) !=
1796 return VecTy->getElementType().getCanonicalType()->isIntegerType() &&
1803 return IsLaxCompatible(FirstType, SecondType) ||
1804 IsLaxCompatible(SecondType, FirstType);
1808 if (!Buffer.empty())
1810 Buffer.append(Feat);
1815 StringRef PriorityString[8] = {
"P0",
"P1",
"P2",
"P3",
1816 "P4",
"P5",
"P6",
"P7"};
1818 assert(Priority > 0 && Priority < 256 &&
"priority out of range");
1820 for (
unsigned BitPos = 0; BitPos < 8; ++BitPos)
1821 if (Priority & (1U << BitPos))
1830 auto [LHS, RHS] = Param.split(
';');
1832 bool IsDefault =
false;
1834 LHS.split(Features,
'+');
1835 for (StringRef Feat : Features) {
1837 if (Feat ==
"default")
1839 else if (!
getASTContext().getTargetInfo().validateCpuSupports(Feat))
1840 return Diag(Loc, diag::warn_unsupported_target_attribute)
1845 if (!RHS.empty() && RHS.consume_front(
"priority=")) {
1847 Diag(Loc, diag::warn_invalid_default_version_priority);
1850 if (RHS.getAsInteger(0, Digit) || Digit < 1 || Digit > 255)
1851 Diag(Loc, diag::warn_version_priority_out_of_range) << RHS;
1867 assert(Params.size() == Locs.size() &&
1868 "Mismatch between number of string parameters and locations");
1870 bool HasDefault =
false;
1871 bool HasNonDefault =
false;
1872 for (
unsigned I = 0, E = Params.size(); I < E; ++I) {
1873 const StringRef Param = Params[I].trim();
1876 auto [LHS, RHS] = Param.split(
';');
1878 bool HasPriority = !RHS.empty() && RHS.consume_front(
"priority=");
1881 return Diag(Loc, diag::warn_unsupported_target_attribute)
1884 if (LHS ==
"default") {
1886 Diag(Loc, diag::warn_target_clone_duplicate_options);
1889 Diag(Loc, diag::warn_invalid_default_version_priority);
1890 NewParams.push_back(LHS);
1896 bool HasCodeGenImpact =
false;
1899 LHS.split(Features,
'+');
1900 for (StringRef Feat : Features) {
1902 if (!
getASTContext().getTargetInfo().validateCpuSupports(Feat)) {
1903 Diag(Loc, diag::warn_unsupported_target_attribute)
1907 if (
getASTContext().getTargetInfo().doesFeatureAffectCodeGen(Feat))
1908 HasCodeGenImpact =
true;
1909 ValidFeatures.push_back(Feat);
1913 if (!HasCodeGenImpact) {
1914 Diag(Loc, diag::warn_target_clone_no_impact_options);
1918 if (ValidFeatures.empty())
1922 llvm::sort(ValidFeatures);
1924 if (llvm::is_contained(NewParams, NewParam)) {
1925 Diag(Loc, diag::warn_target_clone_duplicate_options);
1931 if (RHS.getAsInteger(0, Digit) || Digit < 1 || Digit > 255)
1932 Diag(Loc, diag::warn_version_priority_out_of_range) << RHS;
1938 NewParams.push_back(NewParam);
1939 HasNonDefault =
true;
1942 return !HasNonDefault;
1947 const llvm::StringMap<bool> &FeatureMap) {
1951 if (FeatureMap.lookup(
"sve"))
1955 if (!FeatureMap.lookup(
"sme"))
1956 return Diag(Loc, diag::err_sve_vector_in_non_sve_target) << Ty;
1961 return Diag(Loc, diag::err_sve_vector_in_non_streaming_function) << Ty;
static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, const TargetInfo &Target)
Determine whether a translation unit built using the current language options has the given feature.
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 ARM.
Enumerates target-specific builtins in their own namespaces within namespace clang.
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.
Builtin::Context & BuiltinInfo
const TargetInfo & getTargetInfo() const
void getFunctionFeatureMap(llvm::StringMap< bool > &FeatureMap, const FunctionDecl *) const
Attr - This represents one attribute.
SourceLocation getLoc() const
This class is used for builtin types like 'int'.
unsigned getAuxBuiltinID(unsigned ID) const
Return real builtin ID (i.e.
const char * getRequiredFeatures(unsigned ID) 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
void setArg(unsigned Arg, Expr *ArgExpr)
setArg - Set the specified argument.
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.
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
A reference to a declared variable, function, enum, etc.
SourceLocation getBeginLoc() const
Decl - This represents one declaration (or definition), e.g.
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
SourceLocation getLocation() const
DeclContext * getDeclContext()
This represents one expression.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, bool AllowRelaxedEval=false) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
Represents a function declaration or definition.
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
Represents a prototype with parameter type info, e.g.
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
@ SME_AgnosticZAStateMask
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
One of these records is kept for each identifier that is lexed.
unsigned getBuiltinID() const
Return a value indicating whether this is a builtin function.
IdentifierInfo * getIdentifierInfo() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Describes an entity that is being initialized.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
@ Integer
Permit vector bitcasts between integer vectors with different numbers of elements but the same total ...
@ All
Permit vector bitcasts between all vectors with the same total bit-width.
Flags to identify the types for overloaded Neon builtins.
unsigned getEltSizeInBits() const
EltType getEltType() const
Represents a parameter to a function.
ParsedAttr - Represents a syntactic attribute.
IdentifierLoc * getArgAsIdent(unsigned Arg) const
void setInvalid(bool b=true) const
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this attribute.
bool isArgIdent(unsigned Arg) const
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType withVolatile() const
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool isConstQualified() const
Determine whether this type is const-qualified.
const Type * getTypePtrOrNull() const
bool isAtLeastAsQualifiedAs(QualType Other, const ASTContext &Ctx) const
Determine whether this type is at least as qualified as the other given type, requiring exact equalit...
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
void CheckSMEFunctionDefAttributes(const FunctionDecl *FD)
bool CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool BuiltinARMAtomicStoreHintCall(unsigned BuiltinID, CallExpr *TheCall)
void handleInterruptSaveFPAttr(Decl *D, const ParsedAttr &AL)
bool CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckARMCoprocessorImmediate(const TargetInfo &TI, const Expr *CoprocArg, bool WantCDE)
bool CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckNeonBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckCDEBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool PerformNeonImmChecks(CallExpr *TheCall, SmallVectorImpl< std::tuple< int, int, int, int > > &ImmChecks, int OverloadType=-1)
bool CheckMVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
void handleInterruptAttr(Decl *D, const ParsedAttr &AL)
bool PerformSVEImmChecks(CallExpr *TheCall, SmallVectorImpl< std::tuple< int, int, int > > &ImmChecks)
void handleBuiltinAliasAttr(Decl *D, const ParsedAttr &AL)
@ ArmStreaming
Intrinsic is only available in normal mode.
@ VerifyRuntimeMode
Intrinsic is available both in normal and Streaming-SVE mode.
@ ArmStreamingCompatible
Intrinsic is only available in Streaming-SVE mode.
void handleNewAttr(Decl *D, const ParsedAttr &AL)
bool CheckARMBuiltinExclusiveCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool areCompatibleSveTypes(QualType FirstType, QualType SecondType)
Return true if the given types are an SVE builtin and a VectorType that is a fixed-length representat...
bool checkTargetVersionAttr(const StringRef Param, const SourceLocation Loc, SmallString< 64 > &NewParam)
bool checkSVETypeSupport(QualType Ty, SourceLocation Loc, const FunctionDecl *FD, const llvm::StringMap< bool > &FeatureMap)
bool SveAliasValid(unsigned BuiltinID, llvm::StringRef AliasName)
bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType)
Return true if the given vector types are lax-compatible SVE vector types, false otherwise.
bool CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool MveAliasValid(unsigned BuiltinID, llvm::StringRef AliasName)
bool BuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall)
BuiltinARMMemoryTaggingCall - Handle calls of memory tagging extensions.
void handleCmseNSEntryAttr(Decl *D, const ParsedAttr &AL)
bool CheckImmediateArg(CallExpr *TheCall, unsigned CheckTy, unsigned ArgIdx, unsigned EltBitWidth, unsigned VecBitWidth)
bool BuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, int ArgNum, unsigned ExpectedFieldNum, bool AllowName)
BuiltinARMSpecialReg - Handle a check if argument ArgNum of CallExpr TheCall is an ARM/AArch64 specia...
bool SmeAliasValid(unsigned BuiltinID, llvm::StringRef AliasName)
bool checkTargetClonesAttr(SmallVectorImpl< StringRef > &Params, SmallVectorImpl< SourceLocation > &Locs, SmallVectorImpl< SmallString< 64 > > &NewParams)
bool CdeAliasValid(unsigned BuiltinID, llvm::StringRef AliasName)
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Sema - This implements semantic analysis and AST building for C.
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
Exposes information about the current target.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
IntType getInt64Type() const
@ ARM_LDREX_D
word (32-bit)
virtual unsigned getARMLDREXMask() const
uint32_t getARMCDECoprocMask() const
For ARM targets returns a mask defining which coprocessors are configured as Custom Datapath.
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
The base class of the type hierarchy.
bool isBlockPointerType() const
bool isMFloat8Type() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
bool isSVESizelessBuiltinType() const
Returns true for SVE scalable vector types.
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
QualType getSveEltType(const ASTContext &Ctx) const
Returns the representative type for the element of an SVE builtin type.
bool isBitIntType() const
bool isFloatingType() const
bool isAnyPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isSizelessVectorType() const
Returns true for all scalable vector types.
Represents a GCC generic vector type.
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.
const AstTypeMatcher< PointerType > pointerType
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
static void convertPriorityString(unsigned Priority, SmallString< 64 > &NewParam)
static bool BuiltinAliasValid(unsigned BuiltinID, StringRef AliasName, ArrayRef< IntrinToName > Map, const char *IntrinNames)
static ArmSMEState getSMEState(unsigned BuiltinID)
static bool checkArmStreamingBuiltin(Sema &S, CallExpr *TheCall, const FunctionDecl *FD, SemaARM::ArmStreamingType BuiltinType, unsigned BuiltinID)
SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD)
static uint64_t getSVETypeSize(ASTContext &Context, const BuiltinType *Ty, bool IsStreaming)
getSVETypeSize - Return SVE vector or predicate register size.
@ AANT_ArgumentIdentifier
@ Result
The result type of a method or function.
static bool checkFPMScaleIfConstant(Sema &S, CallExpr *Call, unsigned ArgNum, int64_t Low, int64_t High)
const FunctionProtoType * T
AssignConvertType
AssignConvertType - All of the 'assignment' semantic checks return this enum to indicate whether the ...
bool hasArmZT0State(const FunctionDecl *FD)
Returns whether the given FunctionDecl has Arm ZT0 state.
CastKind
CastKind - The kind of operation required for a conversion.
static QualType getNeonEltType(NeonTypeFlags Flags, ASTContext &Context, bool IsPolyUnsigned, bool IsInt64Long)
getNeonEltType - Return the QualType corresponding to the elements of the vector type specified by th...
static bool checkNewAttrMutualExclusion(Sema &S, const ParsedAttr &AL, const FunctionProtoType *FPT, FunctionType::ArmStateValue CurrentState, StringRef StateName)
static void appendFeature(StringRef Feat, SmallString< 64 > &Buffer)
@ SveFixedLengthData
is AArch64 SVE fixed-length data vector
@ Generic
not a target-specific vector type
@ SveFixedLengthPredicate
is AArch64 SVE fixed-length predicate vector
U cast(CodeGen::Address addr)
bool IsArmStreamingFunction(const FunctionDecl *FD, bool IncludeLocallyStreaming)
Returns whether the given FunctionDecl has an __arm[_locally]_streaming attribute.
ActionResult< Expr * > ExprResult
bool hasArmZAState(const FunctionDecl *FD)
Returns whether the given FunctionDecl has Arm ZA state.
Extra information about a function prototype.
unsigned AArch64SMEAttributes