30 if (BuiltinID == AArch64::BI__builtin_arm_irg) {
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) {
68 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_must_be_pointer)
79 if (BuiltinID == AArch64::BI__builtin_arm_gmi) {
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) {
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)
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);
322 bool IsPolyUnsigned,
bool IsInt64Long) {
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 {
392 if (!llvm::is_contained(
Set, Imm.getSExtValue()))
398 case ImmCheckType::ImmCheck0_31:
402 case ImmCheckType::ImmCheck0_13:
406 case ImmCheckType::ImmCheck0_63:
410 case ImmCheckType::ImmCheck1_16:
414 case ImmCheckType::ImmCheck0_7:
418 case ImmCheckType::ImmCheck1_1:
422 case ImmCheckType::ImmCheck1_3:
426 case ImmCheckType::ImmCheck1_7:
430 case ImmCheckType::ImmCheckExtract:
432 (2048 / EltBitWidth) - 1))
435 case ImmCheckType::ImmCheckCvt:
436 case ImmCheckType::ImmCheckShiftRight:
440 case ImmCheckType::ImmCheckShiftRightNarrow:
444 case ImmCheckType::ImmCheckShiftLeft:
448 case ImmCheckType::ImmCheckLaneIndex:
450 (ContainerBitWidth / EltBitWidth) - 1))
453 case ImmCheckType::ImmCheckLaneIndexCompRotate:
455 TheCall, ArgIdx, 0, (ContainerBitWidth / (2 * EltBitWidth)) - 1))
458 case ImmCheckType::ImmCheckLaneIndexDot:
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:
476 case ImmCheckType::ImmCheck0_2:
480 case ImmCheckType::ImmCheck0_3:
484 case ImmCheckType::ImmCheck0_0:
488 case ImmCheckType::ImmCheck0_15:
492 case ImmCheckType::ImmCheck0_255:
496 case ImmCheckType::ImmCheck1_32:
500 case ImmCheckType::ImmCheck1_64:
504 case ImmCheckType::ImmCheck2_4_Mul2:
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
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
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
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
750 TV =
Result.getLimitedValue(64);
751 if ((TV > 63) || (mask & (1ULL << TV)) == 0)
756 if (PtrArgNum >= 0) {
760 Arg = ICE->getSubExpr();
765 bool IsPolyUnsigned =
Arch == llvm::Triple::aarch64 ||
766 Arch == llvm::Triple::aarch64_32 ||
767 Arch == llvm::Triple::aarch64_be;
770 IsPolyUnsigned, IsInt64Long);
790#define GET_NEON_IMMEDIATE_CHECK
791#include "clang/Basic/arm_fp16.inc"
792#include "clang/Basic/arm_neon.inc"
793#undef GET_NEON_IMMEDIATE_CHECK
804#include "clang/Basic/arm_mve_builtin_sema.inc"
815#include "clang/Basic/arm_cde_builtin_sema.inc"
825 const Expr *CoprocArg,
836 int64_t CoprocNo = CoprocNoAP.getExtValue();
837 assert(CoprocNo >= 0 &&
"Coprocessor immediate must be non-negative");
840 bool IsCDECoproc = CoprocNo <= 7 && (CDECoprocMask & (1 << CoprocNo));
842 if (IsCDECoproc != WantCDE)
852 assert((BuiltinID == ARM::BI__builtin_arm_ldrex ||
853 BuiltinID == ARM::BI__builtin_arm_ldaex ||
854 BuiltinID == ARM::BI__builtin_arm_strex ||
855 BuiltinID == ARM::BI__builtin_arm_stlex ||
856 BuiltinID == AArch64::BI__builtin_arm_ldrex ||
857 BuiltinID == AArch64::BI__builtin_arm_ldaex ||
858 BuiltinID == AArch64::BI__builtin_arm_strex ||
859 BuiltinID == AArch64::BI__builtin_arm_stlex) &&
860 "unexpected ARM builtin");
861 bool IsLdrex = BuiltinID == ARM::BI__builtin_arm_ldrex ||
862 BuiltinID == ARM::BI__builtin_arm_ldaex ||
863 BuiltinID == AArch64::BI__builtin_arm_ldrex ||
864 BuiltinID == AArch64::BI__builtin_arm_ldaex;
878 Expr *PointerArg = TheCall->
getArg(IsLdrex ? 0 : 1);
883 PointerArg = PointerArgRes.
get();
903 CastNeeded = CK_BitCast;
904 Diag(DRE->
getBeginLoc(), diag::ext_typecheck_convert_discards_qualifiers)
905 << PointerArg->
getType() << Context.getPointerType(AddrType)
910 AddrType = Context.getPointerType(AddrType);
914 PointerArg = PointerArgRes.
get();
916 TheCall->
setArg(IsLdrex ? 0 : 1, PointerArg);
921 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intfltptr)
930 unsigned Bits = Context.getTypeSize(ValType);
932 (llvm::isPowerOf2_64(Bits)) && Bits >= 8 && (Mask & (Bits / 8));
942 diag::err_atomic_exclusive_builtin_pointer_size)
944 bool Started =
false;
945 for (
unsigned Size = 1; Size <= 8; Size <<= 1) {
952 if (!(Mask & Size)) {
972 diag::err_atomic_exclusive_builtin_pointer_size_none)
1000 Context, ValType,
false);
1008 TheCall->
setType(Context.IntTy);
1015 if (BuiltinID == ARM::BI__builtin_arm_ldrex ||
1016 BuiltinID == ARM::BI__builtin_arm_ldaex ||
1017 BuiltinID == ARM::BI__builtin_arm_strex ||
1018 BuiltinID == ARM::BI__builtin_arm_stlex) {
1022 if (BuiltinID == ARM::BI__builtin_arm_prefetch) {
1027 if (BuiltinID == ARM::BI__builtin_arm_rsr64 ||
1028 BuiltinID == ARM::BI__builtin_arm_wsr64)
1031 if (BuiltinID == ARM::BI__builtin_arm_rsr ||
1032 BuiltinID == ARM::BI__builtin_arm_rsrp ||
1033 BuiltinID == ARM::BI__builtin_arm_wsr ||
1034 BuiltinID == ARM::BI__builtin_arm_wsrp)
1047 switch (BuiltinID) {
1050 case ARM::BI__builtin_arm_ssat:
1052 case ARM::BI__builtin_arm_usat:
1054 case ARM::BI__builtin_arm_ssat16:
1056 case ARM::BI__builtin_arm_usat16:
1058 case ARM::BI__builtin_arm_vcvtr_f:
1059 case ARM::BI__builtin_arm_vcvtr_d:
1061 case ARM::BI__builtin_arm_dmb:
1063 case ARM::BI__builtin_arm_dsb:
1065 case ARM::BI__builtin_arm_isb:
1067 case ARM::BI__builtin_arm_dbg:
1069 case ARM::BI__builtin_arm_cdp:
1070 case ARM::BI__builtin_arm_cdp2:
1071 case ARM::BI__builtin_arm_mcr:
1072 case ARM::BI__builtin_arm_mcr2:
1073 case ARM::BI__builtin_arm_mrc:
1074 case ARM::BI__builtin_arm_mrc2:
1075 case ARM::BI__builtin_arm_mcrr:
1076 case ARM::BI__builtin_arm_mcrr2:
1077 case ARM::BI__builtin_arm_mrrc:
1078 case ARM::BI__builtin_arm_mrrc2:
1079 case ARM::BI__builtin_arm_ldc:
1080 case ARM::BI__builtin_arm_ldcl:
1081 case ARM::BI__builtin_arm_ldc2:
1082 case ARM::BI__builtin_arm_ldc2l:
1083 case ARM::BI__builtin_arm_stc:
1084 case ARM::BI__builtin_arm_stcl:
1085 case ARM::BI__builtin_arm_stc2:
1086 case ARM::BI__builtin_arm_stc2l:
1096 if (BuiltinID == AArch64::BI__builtin_arm_ldrex ||
1097 BuiltinID == AArch64::BI__builtin_arm_ldaex ||
1098 BuiltinID == AArch64::BI__builtin_arm_strex ||
1099 BuiltinID == AArch64::BI__builtin_arm_stlex) {
1103 if (BuiltinID == AArch64::BI__builtin_arm_prefetch) {
1110 if (BuiltinID == AArch64::BI__builtin_arm_rsr64 ||
1111 BuiltinID == AArch64::BI__builtin_arm_wsr64 ||
1112 BuiltinID == AArch64::BI__builtin_arm_rsr128 ||
1113 BuiltinID == AArch64::BI__builtin_arm_wsr128)
1117 if (BuiltinID == AArch64::BI__builtin_arm_irg ||
1118 BuiltinID == AArch64::BI__builtin_arm_addg ||
1119 BuiltinID == AArch64::BI__builtin_arm_gmi ||
1120 BuiltinID == AArch64::BI__builtin_arm_ldg ||
1121 BuiltinID == AArch64::BI__builtin_arm_stg ||
1122 BuiltinID == AArch64::BI__builtin_arm_subp) {
1126 if (BuiltinID == AArch64::BI__builtin_arm_rsr ||
1127 BuiltinID == AArch64::BI__builtin_arm_rsrp ||
1128 BuiltinID == AArch64::BI__builtin_arm_wsr ||
1129 BuiltinID == AArch64::BI__builtin_arm_wsrp)
1135 if (BuiltinID == AArch64::BI_ReadStatusReg ||
1136 BuiltinID == AArch64::BI_WriteStatusReg || BuiltinID == AArch64::BI__sys)
1139 if (BuiltinID == AArch64::BI__getReg)
1142 if (BuiltinID == AArch64::BI__break)
1145 if (BuiltinID == AArch64::BI__hlt)
1159 unsigned i = 0, l = 0, u = 0;
1160 switch (BuiltinID) {
1161 default:
return false;
1162 case AArch64::BI__builtin_arm_dmb:
1163 case AArch64::BI__dmb:
1164 case AArch64::BI__builtin_arm_dsb:
1165 case AArch64::BI__dsb:
1166 case AArch64::BI__builtin_arm_isb:
1167 case AArch64::BI__isb:
1171 case AArch64::BI__builtin_arm_tcancel: l = 0; u = 65535;
break;
1178struct IntrinToName {
1187 const char *IntrinNames) {
1188 AliasName.consume_front(
"__arm_");
1189 const IntrinToName *It =
1190 llvm::lower_bound(Map, BuiltinID, [](
const IntrinToName &L,
unsigned Id) {
1193 if (It == Map.end() || It->Id != BuiltinID)
1195 StringRef
FullName(&IntrinNames[It->FullName]);
1198 if (It->ShortName == -1)
1200 StringRef
ShortName(&IntrinNames[It->ShortName]);
1205#include "clang/Basic/arm_mve_builtin_aliases.inc"
1213#include "clang/Basic/arm_cde_builtin_aliases.inc"
1234 Diag(AL.
getLoc(), diag::err_attribute_argument_n_type)
1241 StringRef AliasName = cast<FunctionDecl>(
D)->getIdentifier()->getName();
1243 bool IsAArch64 = Context.getTargetInfo().getTriple().isAArch64();
1248 Diag(AL.
getLoc(), diag::err_attribute_arm_builtin_alias);
1252 D->addAttr(::new (Context) ArmBuiltinAliasAttr(Context, AL, Ident));
1258 auto CheckForIncompatibleAttr =
1260 StringRef IncompatibleStateName) {
1261 if (CurrentState == IncompatibleState) {
1262 S.
Diag(AL.
getLoc(), diag::err_attributes_are_not_compatible)
1263 << (std::string(
"'__arm_new(\"") + StateName.str() +
"\")'")
1264 << (std::string(
"'") + IncompatibleStateName.str() +
"(\"" +
1265 StateName.str() +
"\")'")
1280 Diag(AL.
getLoc(), diag::err_missing_arm_state) << AL;
1285 std::vector<StringRef> NewState;
1286 if (
const auto *ExistingAttr =
D->getAttr<ArmNewAttr>()) {
1287 for (StringRef S : ExistingAttr->newArgs())
1288 NewState.push_back(S);
1292 bool HasZT0 =
false;
1293 for (
unsigned I = 0,
E = AL.
getNumArgs(); I !=
E; ++I) {
1294 StringRef StateName;
1299 if (StateName ==
"za")
1301 else if (StateName ==
"zt0")
1304 Diag(LiteralLoc, diag::err_unknown_arm_state) << StateName;
1309 if (!llvm::is_contained(NewState, StateName))
1310 NewState.push_back(StateName);
1313 if (
auto *FPT = dyn_cast<FunctionProtoType>(
D->getFunctionType())) {
1326 D->dropAttr<ArmNewAttr>();
1333 Diag(AL.
getLoc(), diag::err_attribute_not_clinkage) << AL;
1337 const auto *FD = cast<FunctionDecl>(
D);
1338 if (!FD->isExternallyVisible()) {
1339 Diag(AL.
getLoc(), diag::warn_attribute_cmse_entry_static);
1349 Diag(AL.
getLoc(), diag::err_attribute_too_many_arguments) << AL << 1;
1361 ARMInterruptAttr::InterruptType
Kind;
1362 if (!ARMInterruptAttr::ConvertStrToInterruptType(Str,
Kind)) {
1363 Diag(AL.
getLoc(), diag::warn_attribute_type_not_supported)
1364 << AL << Str << ArgLoc;
1368 if (!
D->hasAttr<ARMSaveFPAttr>()) {
1371 Diag(
D->getLocation(), diag::warn_arm_interrupt_vfp_clobber);
1386 if (!
D->hasAttr<ARMInterruptAttr>()) {
1387 D->dropAttr<ARMSaveFPAttr>();
1395 SemaRef.
Diag(
D->getLocation(), diag::warn_arm_interrupt_save_fp_without_vfp_unit);
1396 D->dropAttr<ARMSaveFPAttr>();
1405 bool UsesSM = FD->
hasAttr<ArmLocallyStreamingAttr>();
1406 bool UsesZA =
Attr &&
Attr->isNewZA();
1407 bool UsesZT0 =
Attr &&
Attr->isNewZT0();
1409 if (UsesZA || UsesZT0) {
1417 if (FD->
hasAttr<ArmLocallyStreamingAttr>()) {
1420 diag::warn_sme_locally_streaming_has_vl_args_returns)
1423 return P->getOriginalType()->isSizelessVectorType();
1426 diag::warn_sme_locally_streaming_has_vl_args_returns)
1439 if (UsesSM || UsesZA) {
1440 llvm::StringMap<bool> FeatureMap;
1441 Context.getFunctionFeatureMap(FeatureMap, FD);
1442 if (!FeatureMap.contains(
"sme")) {
1445 diag::err_sme_definition_using_sm_in_non_sme_target);
1448 diag::err_sme_definition_using_za_in_non_sme_target);
1452 llvm::StringMap<bool> FeatureMap;
1453 Context.getFunctionFeatureMap(FeatureMap, FD);
1454 if (!FeatureMap.contains(
"sme2")) {
1456 diag::err_sme_definition_using_zt0_in_non_sme2_target);
1465 uint64_t VScale = IsStreaming ? Context.
getLangOpts().VScaleStreamingMin
1467 if (Ty->
getKind() == BuiltinType::SveBool ||
1468 Ty->
getKind() == BuiltinType::SveCount)
1470 return VScale * 128;
1474 bool IsStreaming =
false;
1498 return BT->getKind() == BuiltinType::SveBool;
1500 return VT->getElementType().getCanonicalType() ==
1503 return Context.getTypeSize(SecondType) ==
1505 Context.hasSameType(
1506 VT->getElementType(),
1507 Context.getBuiltinVectorTypeInfo(BT).ElementType);
1513 return IsValidCast(FirstType, SecondType) ||
1514 IsValidCast(SecondType, FirstType);
1519 bool IsStreaming =
false;
1549 if (BT->getKind() == BuiltinType::SveBool &&
1559 Context.getTypeSize(SecondType) !=
1571 return VecTy->getElementType().getCanonicalType()->isIntegerType() &&
1578 return IsLaxCompatible(FirstType, SecondType) ||
1579 IsLaxCompatible(SecondType, FirstType);
1584 using namespace DiagAttrParams;
1587 Param.split(Features,
'+');
1588 for (StringRef Feat : Features) {
1590 if (Feat ==
"default")
1592 if (!
getASTContext().getTargetInfo().validateCpuSupports(Feat))
1593 return Diag(
Loc, diag::warn_unsupported_target_attribute)
1602 using namespace DiagAttrParams;
1607 assert(Params.size() == Locs.size() &&
1608 "Mismatch between number of string parameters and locations");
1610 bool HasDefault =
false;
1611 bool HasNonDefault =
false;
1612 for (
unsigned I = 0,
E = Params.size(); I <
E; ++I) {
1613 const StringRef Param = Params[I].trim();
1617 return Diag(
Loc, diag::warn_unsupported_target_attribute)
1620 if (Param ==
"default") {
1622 Diag(
Loc, diag::warn_target_clone_duplicate_options);
1624 NewParams.push_back(Param);
1630 bool HasCodeGenImpact =
false;
1633 Param.split(Features,
'+');
1634 for (StringRef Feat : Features) {
1636 if (!
getASTContext().getTargetInfo().validateCpuSupports(Feat)) {
1637 Diag(
Loc, diag::warn_unsupported_target_attribute)
1641 if (
getASTContext().getTargetInfo().doesFeatureAffectCodeGen(Feat))
1642 HasCodeGenImpact =
true;
1643 ValidFeatures.push_back(Feat);
1647 if (!HasCodeGenImpact) {
1648 Diag(
Loc, diag::warn_target_clone_no_impact_options);
1652 if (ValidFeatures.empty())
1656 llvm::sort(ValidFeatures);
1658 if (llvm::is_contained(NewParams, NewParam)) {
1659 Diag(
Loc, diag::warn_target_clone_duplicate_options);
1664 NewParams.push_back(NewParam);
1665 HasNonDefault =
true;
enum clang::sema::@1840::IndirectLocalPathEntry::EntryKind Kind
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 LangOptions & getLangOpts() const
CanQualType UnsignedLongTy
CanQualType UnsignedCharTy
CanQualType UnsignedIntTy
CanQualType UnsignedLongLongTy
CanQualType UnsignedShortTy
const TargetInfo & getTargetInfo() const
void getFunctionFeatureMap(llvm::StringMap< bool > &FeatureMap, const FunctionDecl *) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
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.
A reference to a declared variable, function, enum, etc.
SourceLocation getBeginLoc() const
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocation() const
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.
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
@ 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.
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.
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 checkTargetVersionAttr(const StringRef Str, const SourceLocation Loc)
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 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)
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
Sema - This implements semantic analysis and AST building for C.
bool BuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum, unsigned Multiple)
BuiltinConstantArgMultiple - Handle a check if argument ArgNum of CallExpr TheCall is a constant expr...
AssignConvertType CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, bool Diagnose=true, bool DiagnoseCFAudited=false, bool ConvertRHS=true)
Check assignment constraints for an assignment of RHS to LHSType.
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
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.
ExprResult DefaultLvalueConversion(Expr *E)
bool BuiltinConstantArg(CallExpr *TheCall, int ArgNum, llvm::APSInt &Result)
BuiltinConstantArg - Handle a check if argument ArgNum of CallExpr TheCall is a constant expression.
bool isConstantEvaluatedContext() const
bool checkArgCount(CallExpr *Call, unsigned DesiredArgCount)
Checks that a call expression's argument count is the desired number.
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
bool DiagnoseAssignmentResult(AssignConvertType ConvTy, SourceLocation Loc, QualType DstType, QualType SrcType, Expr *SrcExpr, AssignmentAction Action, bool *Complained=nullptr)
DiagnoseAssignmentResult - Emit a diagnostic, if required, for the assignment conversion type specifi...
bool BuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, int Low, int High, bool RangeIsError=true)
BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr TheCall is a constant express...
bool checkStringLiteralArgumentAttr(const AttributeCommonInfo &CI, const Expr *E, StringRef &Str, SourceLocation *ArgLocation=nullptr)
Check if the argument E is a ASCII string literal.
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
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 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.
const AstTypeMatcher< PointerType > pointerType
Matches pointer types, but does not match Objective-C object pointer types.
The JSON file list parser is used to communicate input to InstallAPI.
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.
CastKind
CastKind - The kind of operation required for a conversion.
const FunctionProtoType * T
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)
@ SveFixedLengthData
is AArch64 SVE fixed-length data vector
@ Generic
not a target-specific vector type
@ SveFixedLengthPredicate
is AArch64 SVE fixed-length predicate vector
@ 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.
bool hasArmZAState(const FunctionDecl *FD)
Returns whether the given FunctionDecl has Arm ZA state.
Extra information about a function prototype.
unsigned AArch64SMEAttributes