30 if (BuiltinID == AArch64::BI__builtin_arm_irg) {
31 if (
SemaRef.checkArgCount(TheCall, 2))
41 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_must_be_pointer)
50 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_must_be_integer)
58 if (BuiltinID == AArch64::BI__builtin_arm_addg) {
59 if (
SemaRef.checkArgCount(TheCall, 2))
68 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_must_be_pointer)
76 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 15);
79 if (BuiltinID == AArch64::BI__builtin_arm_gmi) {
80 if (
SemaRef.checkArgCount(TheCall, 2))
90 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_must_be_pointer)
95 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_must_be_integer)
97 TheCall->
setType(Context.IntTy);
101 if (BuiltinID == AArch64::BI__builtin_arm_ldg ||
102 BuiltinID == AArch64::BI__builtin_arm_stg) {
103 if (
SemaRef.checkArgCount(TheCall, 1))
112 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_must_be_pointer)
117 if (BuiltinID == AArch64::BI__builtin_arm_ldg)
118 TheCall->
setType(FirstArgType);
122 if (BuiltinID == AArch64::BI__builtin_arm_subp) {
135 auto isNull = [&](
Expr *E) ->
bool {
136 return E->isNullPointerConstant(Context,
142 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_null_or_pointer)
146 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_null_or_pointer)
154 if (!Context.typesAreCompatible(
155 Context.getCanonicalType(pointeeA).getUnqualifiedType(),
156 Context.getCanonicalType(pointeeB).getUnqualifiedType())) {
158 diag::err_typecheck_sub_ptr_compatible)
171 SemaRef.ImpCastExprToType(ArgExprA.
get(), ArgTypeB, CK_NullToPointer);
175 SemaRef.ImpCastExprToType(ArgExprB.
get(), ArgTypeA, CK_NullToPointer);
179 TheCall->
setType(Context.LongLongTy);
182 assert(
false &&
"Unhandled ARM MTE intrinsic");
189 int ArgNum,
unsigned ExpectedFieldNum,
191 bool IsARMBuiltin = BuiltinID == ARM::BI__builtin_arm_rsr64 ||
192 BuiltinID == ARM::BI__builtin_arm_wsr64 ||
193 BuiltinID == ARM::BI__builtin_arm_rsr ||
194 BuiltinID == ARM::BI__builtin_arm_rsrp ||
195 BuiltinID == ARM::BI__builtin_arm_wsr ||
196 BuiltinID == ARM::BI__builtin_arm_wsrp;
197 bool IsAArch64Builtin = BuiltinID == AArch64::BI__builtin_arm_rsr64 ||
198 BuiltinID == AArch64::BI__builtin_arm_wsr64 ||
199 BuiltinID == AArch64::BI__builtin_arm_rsr128 ||
200 BuiltinID == AArch64::BI__builtin_arm_wsr128 ||
201 BuiltinID == AArch64::BI__builtin_arm_rsr ||
202 BuiltinID == AArch64::BI__builtin_arm_rsrp ||
203 BuiltinID == AArch64::BI__builtin_arm_wsr ||
204 BuiltinID == AArch64::BI__builtin_arm_wsrp;
205 assert((IsARMBuiltin || IsAArch64Builtin) &&
"Unexpected ARM builtin.");
220 Reg.split(Fields,
":");
222 if (Fields.size() != ExpectedFieldNum && !(AllowName && Fields.size() == 1))
230 if (Fields.size() > 1) {
231 bool FiveFields = Fields.size() == 5;
233 bool ValidString =
true;
235 ValidString &= Fields[0].starts_with_insensitive(
"cp") ||
236 Fields[0].starts_with_insensitive(
"p");
238 Fields[0] = Fields[0].drop_front(
239 Fields[0].starts_with_insensitive(
"cp") ? 2 : 1);
241 ValidString &= Fields[2].starts_with_insensitive(
"c");
243 Fields[2] = Fields[2].drop_front(1);
246 ValidString &= Fields[3].starts_with_insensitive(
"c");
248 Fields[3] = Fields[3].drop_front(1);
254 FieldBitWidths.append({IsAArch64Builtin ? 2 : 4, 3, 4, 4, 3});
256 FieldBitWidths.append({4, 3, 4});
258 for (
unsigned i = 0; i < Fields.size(); ++i) {
260 ValidString &= !Fields[i].getAsInteger(10, IntField);
261 ValidString &= (IntField >= 0 && IntField < (1 << FieldBitWidths[i]));
267 }
else if (IsAArch64Builtin && Fields.size() == 1) {
275 if (BuiltinID == AArch64::BI__builtin_arm_rsr128 ||
276 BuiltinID == AArch64::BI__builtin_arm_wsr128)
281 auto MaxLimit = llvm::StringSwitch<std::optional<unsigned>>(Reg)
282 .CaseLower(
"spsel", 15)
283 .CaseLower(
"daifclr", 15)
284 .CaseLower(
"daifset", 15)
285 .CaseLower(
"pan", 15)
286 .CaseLower(
"uao", 15)
287 .CaseLower(
"dit", 15)
288 .CaseLower(
"ssbs", 15)
289 .CaseLower(
"tco", 15)
290 .CaseLower(
"allint", 1)
292 .Default(std::nullopt);
312 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, *MaxLimit);
322 bool IsPolyUnsigned,
bool IsInt64Long) {
325 return Flags.
isUnsigned() ? Context.UnsignedCharTy : Context.SignedCharTy;
327 return Flags.
isUnsigned() ? Context.UnsignedShortTy : Context.ShortTy;
329 return Flags.
isUnsigned() ? Context.UnsignedIntTy : Context.IntTy;
332 return Flags.
isUnsigned() ? Context.UnsignedLongTy : Context.LongTy;
334 return Flags.
isUnsigned() ? Context.UnsignedLongLongTy
335 : Context.LongLongTy;
337 return IsPolyUnsigned ? Context.UnsignedCharTy : Context.SignedCharTy;
339 return IsPolyUnsigned ? Context.UnsignedShortTy : Context.ShortTy;
342 return Context.UnsignedLongTy;
344 return Context.UnsignedLongLongTy;
348 return Context.HalfTy;
350 return Context.FloatTy;
352 return Context.DoubleTy;
354 return Context.BFloat16Ty;
356 return Context.MFloat8Ty;
358 llvm_unreachable(
"Invalid NeonTypeFlag!");
376 unsigned ArgIdx,
unsigned EltBitWidth,
377 unsigned ContainerBitWidth) {
380 auto CheckImmediateInSet = [&](std::initializer_list<int64_t>
Set,
381 int ErrDiag) ->
bool {
389 if (
SemaRef.BuiltinConstantArg(TheCall, ArgIdx, Imm))
392 if (!llvm::is_contained(
Set, Imm.getSExtValue()))
398 case ImmCheckType::ImmCheck0_31:
399 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 31))
402 case ImmCheckType::ImmCheck0_13:
403 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 13))
406 case ImmCheckType::ImmCheck0_63:
407 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 63))
410 case ImmCheckType::ImmCheck1_16:
411 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 16))
414 case ImmCheckType::ImmCheck0_7:
415 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 7))
418 case ImmCheckType::ImmCheck1_1:
419 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 1))
422 case ImmCheckType::ImmCheck1_3:
423 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 3))
426 case ImmCheckType::ImmCheck1_7:
427 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 7))
430 case ImmCheckType::ImmCheckExtract:
431 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0,
432 (2048 / EltBitWidth) - 1))
435 case ImmCheckType::ImmCheckCvt:
436 case ImmCheckType::ImmCheckShiftRight:
437 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, EltBitWidth))
440 case ImmCheckType::ImmCheckShiftRightNarrow:
441 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, EltBitWidth / 2))
444 case ImmCheckType::ImmCheckShiftLeft:
445 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, EltBitWidth - 1))
448 case ImmCheckType::ImmCheckLaneIndex:
449 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0,
450 (ContainerBitWidth / EltBitWidth) - 1))
453 case ImmCheckType::ImmCheckLaneIndexCompRotate:
454 if (
SemaRef.BuiltinConstantArgRange(
455 TheCall, ArgIdx, 0, (ContainerBitWidth / (2 * EltBitWidth)) - 1))
458 case ImmCheckType::ImmCheckLaneIndexDot:
459 if (
SemaRef.BuiltinConstantArgRange(
460 TheCall, ArgIdx, 0, (ContainerBitWidth / (4 * EltBitWidth)) - 1))
463 case ImmCheckType::ImmCheckComplexRot90_270:
464 if (CheckImmediateInSet({90, 270}, diag::err_rotation_argument_to_cadd))
467 case ImmCheckType::ImmCheckComplexRotAll90:
468 if (CheckImmediateInSet({0, 90, 180, 270},
469 diag::err_rotation_argument_to_cmla))
472 case ImmCheckType::ImmCheck0_1:
473 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 1))
476 case ImmCheckType::ImmCheck0_2:
477 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 2))
480 case ImmCheckType::ImmCheck0_3:
481 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 3))
484 case ImmCheckType::ImmCheck0_0:
485 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 0))
488 case ImmCheckType::ImmCheck0_15:
489 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 15))
492 case ImmCheckType::ImmCheck0_255:
493 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 255))
496 case ImmCheckType::ImmCheck1_32:
497 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 32))
500 case ImmCheckType::ImmCheck1_64:
501 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 64))
504 case ImmCheckType::ImmCheck2_4_Mul2:
505 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 2, 4) ||
506 SemaRef.BuiltinConstantArgMultiple(TheCall, ArgIdx, 2))
517 bool HasError =
false;
519 for (
const auto &I : ImmChecks) {
520 auto [ArgIdx, CheckTy, ElementBitWidth, VecBitWidth] = I;
522 if (OverloadType >= 0)
534 bool HasError =
false;
536 for (
const auto &I : ImmChecks) {
537 auto [ArgIdx, CheckTy, ElementBitWidth] = I;
546 if (FD->
hasAttr<ArmLocallyStreamingAttr>())
550 if (FPT->getAArch64SMEAttributes() &
553 if (FPT->getAArch64SMEAttributes() &
564 unsigned BuiltinID) {
572 llvm::StringMap<bool> CallerFeatures;
579 const auto FindTopLevelPipe = [](
const char *S) {
581 unsigned I = 0, E = strlen(S);
583 if (S[I] ==
'|' && Depth == 0)
587 else if (S[I] ==
')')
593 const char *RequiredFeatures =
595 unsigned PipeIdx = FindTopLevelPipe(RequiredFeatures);
596 assert(PipeIdx != 0 && PipeIdx != strlen(RequiredFeatures) &&
597 "Expected feature string of the form 'SVE-EXPR|SME-EXPR'");
598 StringRef NonStreamingBuiltinGuard = StringRef(RequiredFeatures, PipeIdx);
599 StringRef StreamingBuiltinGuard = StringRef(RequiredFeatures + PipeIdx + 1);
602 NonStreamingBuiltinGuard, CallerFeatures);
604 StreamingBuiltinGuard, CallerFeatures);
606 if (SatisfiesSVE && SatisfiesSME)
609 else if (SatisfiesSVE)
611 else if (SatisfiesSME)
620 S.
Diag(TheCall->
getBeginLoc(), diag::err_attribute_arm_sm_incompat_builtin)
624 S.
Diag(TheCall->
getBeginLoc(), diag::err_attribute_arm_sm_incompat_builtin)
636#define GET_SME_BUILTIN_GET_STATE
637#include "clang/Basic/arm_sme_builtins_za_state.inc"
638#undef GET_SME_BUILTIN_GET_STATE
645 SemaRef.getCurFunctionDecl(
true)) {
649#define GET_SME_STREAMING_ATTRS
650#include "clang/Basic/arm_sme_streaming_attrs.inc"
651#undef GET_SME_STREAMING_ATTRS
660 diag::warn_attribute_arm_za_builtin_no_za_state)
665 diag::warn_attribute_arm_zt0_builtin_no_zt0_state)
675#define GET_SME_IMMEDIATE_CHECK
676#include "clang/Basic/arm_sme_sema_rangechecks.inc"
677#undef GET_SME_IMMEDIATE_CHECK
686 SemaRef.getCurFunctionDecl(
true)) {
690#define GET_SVE_STREAMING_ATTRS
691#include "clang/Basic/arm_sve_streaming_attrs.inc"
692#undef GET_SVE_STREAMING_ATTRS
704#define GET_SVE_IMMEDIATE_CHECK
705#include "clang/Basic/arm_sve_sema_rangechecks.inc"
706#undef GET_SVE_IMMEDIATE_CHECK
716 SemaRef.getCurFunctionDecl(
true)) {
722#define GET_NEON_STREAMING_COMPAT_FLAG
723#include "clang/Basic/arm_neon.inc"
724#undef GET_NEON_STREAMING_COMPAT_FLAG
735 bool HasConstPtr =
false;
737#define GET_NEON_OVERLOAD_CHECK
738#include "clang/Basic/arm_fp16.inc"
739#include "clang/Basic/arm_neon.inc"
740#undef GET_NEON_OVERLOAD_CHECK
752 TV =
Result.getLimitedValue(64);
753 if ((TV > 63) || (mask & (1ULL << TV)) == 0)
758 if (PtrArgNum >= 0) {
762 Arg = ICE->getSubExpr();
767 bool IsPolyUnsigned =
Arch == llvm::Triple::aarch64 ||
768 Arch == llvm::Triple::aarch64_32 ||
769 Arch == llvm::Triple::aarch64_be;
772 IsPolyUnsigned, IsInt64Long);
777 ConvTy =
SemaRef.CheckSingleAssignmentConstraints(LHSTy, RHS);
792#define GET_NEON_IMMEDIATE_CHECK
793#include "clang/Basic/arm_fp16.inc"
794#include "clang/Basic/arm_neon.inc"
795#undef GET_NEON_IMMEDIATE_CHECK
806#include "clang/Basic/arm_mve_builtin_sema.inc"
817#include "clang/Basic/arm_cde_builtin_sema.inc"
827 const Expr *CoprocArg,
830 if (
SemaRef.isConstantEvaluatedContext())
838 int64_t CoprocNo = CoprocNoAP.getExtValue();
839 assert(CoprocNo >= 0 &&
"Coprocessor immediate must be non-negative");
842 bool IsCDECoproc = CoprocNo <= 7 && (CDECoprocMask & (1 << CoprocNo));
844 if (IsCDECoproc != WantCDE)
854 assert((BuiltinID == ARM::BI__builtin_arm_ldrex ||
855 BuiltinID == ARM::BI__builtin_arm_ldrexd ||
856 BuiltinID == ARM::BI__builtin_arm_ldaex ||
857 BuiltinID == ARM::BI__builtin_arm_strex ||
858 BuiltinID == ARM::BI__builtin_arm_strexd ||
859 BuiltinID == ARM::BI__builtin_arm_stlex ||
860 BuiltinID == AArch64::BI__builtin_arm_ldrex ||
861 BuiltinID == AArch64::BI__builtin_arm_ldaex ||
862 BuiltinID == AArch64::BI__builtin_arm_strex ||
863 BuiltinID == AArch64::BI__builtin_arm_stlex) &&
864 "unexpected ARM builtin");
865 bool IsLdrex = BuiltinID == ARM::BI__builtin_arm_ldrex ||
866 BuiltinID == ARM::BI__builtin_arm_ldrexd ||
867 BuiltinID == ARM::BI__builtin_arm_ldaex ||
868 BuiltinID == AArch64::BI__builtin_arm_ldrex ||
869 BuiltinID == AArch64::BI__builtin_arm_ldaex;
870 bool IsDoubleWord = BuiltinID == ARM::BI__builtin_arm_ldrexd ||
871 BuiltinID == ARM::BI__builtin_arm_strexd;
878 if (
SemaRef.checkArgCount(TheCall, IsLdrex ? 1 : 2))
885 Expr *PointerArg = TheCall->
getArg(IsLdrex ? 0 : 1);
887 SemaRef.DefaultFunctionArrayLvalueConversion(PointerArg);
890 PointerArg = PointerArgRes.
get();
910 CastNeeded = CK_BitCast;
911 Diag(DRE->
getBeginLoc(), diag::ext_typecheck_convert_discards_qualifiers)
912 << PointerArg->
getType() << Context.getPointerType(AddrType)
917 AddrType = Context.getPointerType(AddrType);
918 PointerArgRes =
SemaRef.ImpCastExprToType(PointerArg, AddrType, CastNeeded);
921 PointerArg = PointerArgRes.
get();
923 TheCall->
setArg(IsLdrex ? 0 : 1, PointerArg);
928 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intfltptr)
937 unsigned Bits = Context.getTypeSize(ValType);
944 (llvm::isPowerOf2_64(Bits)) && Bits >= 8 && (Mask & (Bits / 8));
954 diag::err_atomic_exclusive_builtin_pointer_size)
956 bool Started =
false;
957 for (
unsigned Size = 1; Size <= 8; Size <<= 1) {
964 if (!(Mask & Size)) {
983 bool EmitDoubleWordDiagnostic =
986 diag::err_atomic_exclusive_builtin_pointer_size_none)
987 << (EmitDoubleWordDiagnostic ? 1 : 0)
1015 Context, ValType,
false);
1023 TheCall->
setType(Context.IntTy);
1030 if (BuiltinID == ARM::BI__builtin_arm_ldrex ||
1031 BuiltinID == ARM::BI__builtin_arm_ldrexd ||
1032 BuiltinID == ARM::BI__builtin_arm_ldaex ||
1033 BuiltinID == ARM::BI__builtin_arm_strex ||
1034 BuiltinID == ARM::BI__builtin_arm_strexd ||
1035 BuiltinID == ARM::BI__builtin_arm_stlex) {
1039 if (BuiltinID == ARM::BI__builtin_arm_prefetch) {
1040 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) ||
1041 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 1);
1044 if (BuiltinID == ARM::BI__builtin_arm_rsr64 ||
1045 BuiltinID == ARM::BI__builtin_arm_wsr64)
1048 if (BuiltinID == ARM::BI__builtin_arm_rsr ||
1049 BuiltinID == ARM::BI__builtin_arm_rsrp ||
1050 BuiltinID == ARM::BI__builtin_arm_wsr ||
1051 BuiltinID == ARM::BI__builtin_arm_wsrp)
1064 switch (BuiltinID) {
1067 case ARM::BI__builtin_arm_ssat:
1068 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 1, 32);
1069 case ARM::BI__builtin_arm_usat:
1070 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31);
1071 case ARM::BI__builtin_arm_ssat16:
1072 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 1, 16);
1073 case ARM::BI__builtin_arm_usat16:
1074 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 15);
1075 case ARM::BI__builtin_arm_vcvtr_f:
1076 case ARM::BI__builtin_arm_vcvtr_d:
1077 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1);
1078 case ARM::BI__builtin_arm_dmb:
1080 case ARM::BI__builtin_arm_dsb:
1082 case ARM::BI__builtin_arm_isb:
1084 case ARM::BI__builtin_arm_dbg:
1085 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 15);
1086 case ARM::BI__builtin_arm_cdp:
1087 case ARM::BI__builtin_arm_cdp2:
1088 case ARM::BI__builtin_arm_mcr:
1089 case ARM::BI__builtin_arm_mcr2:
1090 case ARM::BI__builtin_arm_mrc:
1091 case ARM::BI__builtin_arm_mrc2:
1092 case ARM::BI__builtin_arm_mcrr:
1093 case ARM::BI__builtin_arm_mcrr2:
1094 case ARM::BI__builtin_arm_mrrc:
1095 case ARM::BI__builtin_arm_mrrc2:
1096 case ARM::BI__builtin_arm_ldc:
1097 case ARM::BI__builtin_arm_ldcl:
1098 case ARM::BI__builtin_arm_ldc2:
1099 case ARM::BI__builtin_arm_ldc2l:
1100 case ARM::BI__builtin_arm_stc:
1101 case ARM::BI__builtin_arm_stcl:
1102 case ARM::BI__builtin_arm_stc2:
1103 case ARM::BI__builtin_arm_stc2l:
1104 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 15) ||
1135 Expr *PointerArg = PtrRes.
get();
1142 diag::err_atomic_builtin_must_be_pointer)
1151 diag::err_atomic_builtin_cannot_be_const)
1157 unsigned Bits = ValType->
isIntegerType() ? Context.getTypeSize(ValType) : 0;
1158 if (Bits != 8 && Bits != 16 && Bits != 32 && Bits != 64) {
1160 diag::err_arm_atomic_store_with_stshh_bad_type)
1169 if (!Context.hasSameType(ValArgType, ValType)) {
1171 diag::err_arm_atomic_store_with_stshh_bad_value_type)
1177 std::optional<llvm::APSInt> OrderValOpt =
1181 diag::err_arm_atomic_store_with_stshh_bad_order)
1187 int64_t Order = OrderValOpt->getSExtValue();
1188 if (Order != 0 && Order != 3 && Order != 5) {
1190 diag::err_arm_atomic_store_with_stshh_bad_order)
1210 if (BuiltinID == AArch64::BI__builtin_arm_ldrex ||
1211 BuiltinID == AArch64::BI__builtin_arm_ldaex ||
1212 BuiltinID == AArch64::BI__builtin_arm_strex ||
1213 BuiltinID == AArch64::BI__builtin_arm_stlex) {
1217 if (BuiltinID == AArch64::BI__builtin_arm_atomic_store_with_stshh)
1220 if (BuiltinID == AArch64::BI__builtin_arm_prefetch) {
1221 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) ||
1222 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3) ||
1223 SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 1) ||
1224 SemaRef.BuiltinConstantArgRange(TheCall, 4, 0, 1);
1227 if (BuiltinID == AArch64::BI__builtin_arm_range_prefetch_x) {
1228 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) ||
1229 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 1) ||
1230 SemaRef.BuiltinConstantArgRange(TheCall, 3, -2097152, 2097151) ||
1231 SemaRef.BuiltinConstantArgRange(TheCall, 4, 1, 65536) ||
1232 SemaRef.BuiltinConstantArgRange(TheCall, 5, -2097152, 2097151);
1235 if (BuiltinID == AArch64::BI__builtin_arm_range_prefetch) {
1236 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) ||
1237 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 1);
1240 if (BuiltinID == AArch64::BI__builtin_arm_rsr64 ||
1241 BuiltinID == AArch64::BI__builtin_arm_wsr64 ||
1242 BuiltinID == AArch64::BI__builtin_arm_rsr128 ||
1243 BuiltinID == AArch64::BI__builtin_arm_wsr128)
1247 if (BuiltinID == AArch64::BI__builtin_arm_irg ||
1248 BuiltinID == AArch64::BI__builtin_arm_addg ||
1249 BuiltinID == AArch64::BI__builtin_arm_gmi ||
1250 BuiltinID == AArch64::BI__builtin_arm_ldg ||
1251 BuiltinID == AArch64::BI__builtin_arm_stg ||
1252 BuiltinID == AArch64::BI__builtin_arm_subp) {
1256 if (BuiltinID == AArch64::BI__builtin_arm_rsr ||
1257 BuiltinID == AArch64::BI__builtin_arm_rsrp ||
1258 BuiltinID == AArch64::BI__builtin_arm_wsr ||
1259 BuiltinID == AArch64::BI__builtin_arm_wsrp)
1265 if (BuiltinID == AArch64::BI_ReadStatusReg ||
1266 BuiltinID == AArch64::BI_WriteStatusReg || BuiltinID == AArch64::BI__sys)
1267 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 0x7fff);
1269 if (BuiltinID == AArch64::BI__getReg)
1270 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 31);
1272 if (BuiltinID == AArch64::BI__break)
1273 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 0xffff);
1275 if (BuiltinID == AArch64::BI__hlt)
1276 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 0xffff);
1289 unsigned i = 0, l = 0, u = 0;
1290 switch (BuiltinID) {
1291 default:
return false;
1292 case AArch64::BI__builtin_arm_dmb:
1293 case AArch64::BI__dmb:
1294 case AArch64::BI__builtin_arm_dsb:
1295 case AArch64::BI__dsb:
1296 case AArch64::BI__builtin_arm_isb:
1297 case AArch64::BI__isb:
1303 return SemaRef.BuiltinConstantArgRange(TheCall, i, l, u + l);
1307struct IntrinToName {
1316 const char *IntrinNames) {
1317 AliasName.consume_front(
"__arm_");
1318 const IntrinToName *It =
1319 llvm::lower_bound(Map, BuiltinID, [](
const IntrinToName &L,
unsigned Id) {
1322 if (It == Map.end() || It->Id != BuiltinID)
1324 StringRef FullName(&IntrinNames[It->FullName]);
1325 if (AliasName == FullName)
1327 if (It->ShortName == -1)
1329 StringRef ShortName(&IntrinNames[It->ShortName]);
1330 return AliasName == ShortName;
1334#include "clang/Basic/arm_mve_builtin_aliases.inc"
1342#include "clang/Basic/arm_cde_builtin_aliases.inc"
1363 Diag(AL.
getLoc(), diag::err_attribute_argument_n_type)
1372 bool IsAArch64 = Context.getTargetInfo().getTriple().isAArch64();
1377 Diag(AL.
getLoc(), diag::err_attribute_arm_builtin_alias);
1381 D->
addAttr(::new (Context) ArmBuiltinAliasAttr(Context, AL, Ident));
1387 auto CheckForIncompatibleAttr =
1389 StringRef IncompatibleStateName) {
1390 if (CurrentState == IncompatibleState) {
1391 S.
Diag(AL.
getLoc(), diag::err_attributes_are_not_compatible)
1392 << (std::string(
"'__arm_new(\"") + StateName.str() +
"\")'")
1393 << (std::string(
"'") + IncompatibleStateName.str() +
"(\"" +
1394 StateName.str() +
"\")'")
1409 Diag(AL.
getLoc(), diag::err_missing_arm_state) << AL;
1414 std::vector<StringRef> NewState;
1415 if (
const auto *ExistingAttr = D->
getAttr<ArmNewAttr>()) {
1416 for (StringRef S : ExistingAttr->newArgs())
1417 NewState.push_back(S);
1421 bool HasZT0 =
false;
1422 for (
unsigned I = 0, E = AL.
getNumArgs(); I != E; ++I) {
1423 StringRef StateName;
1425 if (!
SemaRef.checkStringLiteralArgumentAttr(AL, I, StateName, &LiteralLoc))
1428 if (StateName ==
"za")
1430 else if (StateName ==
"zt0")
1433 Diag(LiteralLoc, diag::err_unknown_arm_state) << StateName;
1438 if (!llvm::is_contained(NewState, StateName))
1439 NewState.push_back(StateName);
1462 Diag(AL.
getLoc(), diag::err_attribute_not_clinkage) << AL;
1467 if (!FD->isExternallyVisible()) {
1468 Diag(AL.
getLoc(), diag::warn_attribute_cmse_entry_static);
1478 Diag(AL.
getLoc(), diag::err_attribute_too_many_arguments) << AL << 1;
1487 else if (!
SemaRef.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
1490 ARMInterruptAttr::InterruptType Kind;
1491 if (!ARMInterruptAttr::ConvertStrToInterruptType(Str, Kind)) {
1492 Diag(AL.
getLoc(), diag::warn_attribute_type_not_supported)
1493 << AL << Str << ArgLoc;
1497 if (!D->
hasAttr<ARMSaveFPAttr>()) {
1512 SemaRef.ARM().handleInterruptAttr(D, AL);
1515 if (!D->
hasAttr<ARMInterruptAttr>()) {
1521 bool VFP =
SemaRef.Context.getTargetInfo().hasFeature(
"vfp");
1534 bool UsesSM = FD->
hasAttr<ArmLocallyStreamingAttr>();
1535 bool UsesZA =
Attr &&
Attr->isNewZA();
1536 bool UsesZT0 =
Attr &&
Attr->isNewZT0();
1538 if (UsesZA || UsesZT0) {
1546 if (FD->
hasAttr<ArmLocallyStreamingAttr>()) {
1549 diag::warn_sme_locally_streaming_has_vl_args_returns)
1552 return P->getOriginalType()->isSizelessVectorType();
1555 diag::warn_sme_locally_streaming_has_vl_args_returns)
1568 if (UsesSM || UsesZA) {
1569 llvm::StringMap<bool> FeatureMap;
1570 Context.getFunctionFeatureMap(FeatureMap, FD);
1571 if (!FeatureMap.contains(
"sme")) {
1574 diag::err_sme_definition_using_sm_in_non_sme_target);
1577 diag::err_sme_definition_using_za_in_non_sme_target);
1581 llvm::StringMap<bool> FeatureMap;
1582 Context.getFunctionFeatureMap(FeatureMap, FD);
1583 if (!FeatureMap.contains(
"sme2")) {
1585 diag::err_sme_definition_using_zt0_in_non_sme2_target);
1594 uint64_t VScale = IsStreaming ? Context.getLangOpts().VScaleStreamingMin
1595 : Context.getLangOpts().VScaleMin;
1596 if (Ty->
getKind() == BuiltinType::SveBool ||
1597 Ty->
getKind() == BuiltinType::SveCount)
1598 return (VScale * 128) / Context.getCharWidth();
1599 return VScale * 128;
1603 bool IsStreaming =
false;
1607 SemaRef.getCurFunctionDecl(
true)) {
1610 if (T->getAArch64SMEAttributes() &
1627 return BT->getKind() == BuiltinType::SveBool;
1629 return VT->getElementType().getCanonicalType() ==
1631 BT->getKind() != BuiltinType::SveBool;
1633 return Context.getTypeSize(SecondType) ==
1635 Context.hasSameType(
1636 VT->getElementType(),
1637 Context.getBuiltinVectorTypeInfo(BT).ElementType);
1643 return IsValidCast(FirstType, SecondType) ||
1644 IsValidCast(SecondType, FirstType);
1649 bool IsStreaming =
false;
1653 SemaRef.getCurFunctionDecl(
true)) {
1656 if (T->getAArch64SMEAttributes() &
1679 if (BT->getKind() == BuiltinType::SveBool &&
1689 Context.getTypeSize(SecondType) !=
1701 return VecTy->getElementType().getCanonicalType()->isIntegerType() &&
1708 return IsLaxCompatible(FirstType, SecondType) ||
1709 IsLaxCompatible(SecondType, FirstType);
1713 if (!Buffer.empty())
1715 Buffer.append(Feat);
1720 StringRef PriorityString[8] = {
"P0",
"P1",
"P2",
"P3",
1721 "P4",
"P5",
"P6",
"P7"};
1723 assert(Priority > 0 && Priority < 256 &&
"priority out of range");
1725 for (
unsigned BitPos = 0; BitPos < 8; ++BitPos)
1726 if (Priority & (1U << BitPos))
1735 auto [LHS, RHS] = Param.split(
';');
1737 bool IsDefault =
false;
1739 LHS.split(Features,
'+');
1740 for (StringRef Feat : Features) {
1742 if (Feat ==
"default")
1744 else if (!
getASTContext().getTargetInfo().validateCpuSupports(Feat))
1745 return Diag(Loc, diag::warn_unsupported_target_attribute)
1750 if (!RHS.empty() && RHS.consume_front(
"priority=")) {
1752 Diag(Loc, diag::warn_invalid_default_version_priority);
1755 if (RHS.getAsInteger(0, Digit) || Digit < 1 || Digit > 255)
1756 Diag(Loc, diag::warn_version_priority_out_of_range) << RHS;
1772 assert(Params.size() == Locs.size() &&
1773 "Mismatch between number of string parameters and locations");
1775 bool HasDefault =
false;
1776 bool HasNonDefault =
false;
1777 for (
unsigned I = 0, E = Params.size(); I < E; ++I) {
1778 const StringRef Param = Params[I].trim();
1781 auto [LHS, RHS] = Param.split(
';');
1783 bool HasPriority = !RHS.empty() && RHS.consume_front(
"priority=");
1786 return Diag(Loc, diag::warn_unsupported_target_attribute)
1789 if (LHS ==
"default") {
1791 Diag(Loc, diag::warn_target_clone_duplicate_options);
1794 Diag(Loc, diag::warn_invalid_default_version_priority);
1795 NewParams.push_back(LHS);
1801 bool HasCodeGenImpact =
false;
1804 LHS.split(Features,
'+');
1805 for (StringRef Feat : Features) {
1807 if (!
getASTContext().getTargetInfo().validateCpuSupports(Feat)) {
1808 Diag(Loc, diag::warn_unsupported_target_attribute)
1812 if (
getASTContext().getTargetInfo().doesFeatureAffectCodeGen(Feat))
1813 HasCodeGenImpact =
true;
1814 ValidFeatures.push_back(Feat);
1818 if (!HasCodeGenImpact) {
1819 Diag(Loc, diag::warn_target_clone_no_impact_options);
1823 if (ValidFeatures.empty())
1827 llvm::sort(ValidFeatures);
1829 if (llvm::is_contained(NewParams, NewParam)) {
1830 Diag(Loc, diag::warn_target_clone_duplicate_options);
1836 if (RHS.getAsInteger(0, Digit) || Digit < 1 || Digit > 255)
1837 Diag(Loc, diag::warn_version_priority_out_of_range) << RHS;
1843 NewParams.push_back(NewParam);
1844 HasNonDefault =
true;
1854 const llvm::StringMap<bool> &FeatureMap) {
1858 if (FeatureMap.lookup(
"sve"))
1862 if (!FeatureMap.lookup(
"sme"))
1863 return Diag(Loc, diag::err_sve_vector_in_non_sve_target) << Ty;
1868 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.
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.
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...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
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.
QualType getPointeeType() const
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 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)
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.
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
bool BuiltinConstantArgRange(CallExpr *TheCall, unsigned ArgNum, int Low, int High, bool RangeIsError=true)
BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr TheCall is a constant express...
bool checkArgCount(CallExpr *Call, unsigned DesiredArgCount)
Checks that a call expression's argument count is the desired number.
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 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,...
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 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
The JSON file list parser is used to communicate input to InstallAPI.
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.
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.
static bool CheckAArch64AtomicStoreWithStshhCall(SemaARM &S, CallExpr *TheCall)
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)
@ None
The alignment was not explicit in code.
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