34#include "llvm/ADT/StringExtras.h"
35#include "llvm/Analysis/ValueTracking.h"
36#include "llvm/IR/Assumptions.h"
37#include "llvm/IR/AttributeMask.h"
38#include "llvm/IR/Attributes.h"
39#include "llvm/IR/CallingConv.h"
40#include "llvm/IR/DataLayout.h"
41#include "llvm/IR/InlineAsm.h"
42#include "llvm/IR/IntrinsicInst.h"
43#include "llvm/IR/Intrinsics.h"
44#include "llvm/IR/Type.h"
45#include "llvm/Transforms/Utils/Local.h"
55 return llvm::CallingConv::C;
57 return llvm::CallingConv::X86_StdCall;
59 return llvm::CallingConv::X86_FastCall;
61 return llvm::CallingConv::X86_RegCall;
63 return llvm::CallingConv::X86_ThisCall;
65 return llvm::CallingConv::Win64;
67 return llvm::CallingConv::X86_64_SysV;
69 return llvm::CallingConv::ARM_AAPCS;
71 return llvm::CallingConv::ARM_AAPCS_VFP;
73 return llvm::CallingConv::Intel_OCL_BI;
76 return llvm::CallingConv::C;
79 return llvm::CallingConv::X86_VectorCall;
81 return llvm::CallingConv::AArch64_VectorCall;
83 return llvm::CallingConv::AArch64_SVE_VectorCall;
85 return llvm::CallingConv::SPIR_FUNC;
87 return CGM.getTargetCodeGenInfo().getDeviceKernelCallingConv();
89 return llvm::CallingConv::PreserveMost;
91 return llvm::CallingConv::PreserveAll;
93 return llvm::CallingConv::Swift;
95 return llvm::CallingConv::SwiftTail;
97 return llvm::CallingConv::M68k_RTD;
99 return llvm::CallingConv::PreserveNone;
103#define CC_VLS_CASE(ABI_VLEN) \
104 case CC_RISCVVLSCall_##ABI_VLEN: \
105 return llvm::CallingConv::RISCV_VLSCall_##ABI_VLEN;
130 RecTy = Context.getCanonicalTagType(RD);
132 RecTy = Context.VoidTy;
137 return Context.getPointerType(RecTy);
170 assert(paramInfos.size() <= prefixArgs);
171 assert(proto->
getNumParams() + prefixArgs <= totalArgs);
173 paramInfos.reserve(totalArgs);
176 paramInfos.resize(prefixArgs);
180 paramInfos.push_back(ParamInfo);
182 if (ParamInfo.hasPassObjectSize())
183 paramInfos.emplace_back();
186 assert(paramInfos.size() <= totalArgs &&
187 "Did we forget to insert pass_object_size args?");
189 paramInfos.resize(totalArgs);
199 if (!FPT->hasExtParameterInfos()) {
200 assert(paramInfos.empty() &&
201 "We have paramInfos, but the prototype doesn't?");
202 prefix.append(FPT->param_type_begin(), FPT->param_type_end());
206 unsigned PrefixSize = prefix.size();
210 prefix.reserve(prefix.size() + FPT->getNumParams());
212 auto ExtInfos = FPT->getExtParameterInfos();
213 assert(ExtInfos.size() == FPT->getNumParams());
214 for (
unsigned I = 0, E = FPT->getNumParams(); I != E; ++I) {
215 prefix.push_back(FPT->getParamType(I));
216 if (ExtInfos[I].hasPassObjectSize())
241 FTP->getExtInfo(), paramInfos,
Required);
251 return ::arrangeLLVMFunctionInfo(*
this,
false, argTypes,
256 bool IsTargetDefaultMSABI) {
261 if (D->
hasAttr<FastCallAttr>())
267 if (D->
hasAttr<ThisCallAttr>())
270 if (D->
hasAttr<VectorCallAttr>())
276 if (PcsAttr *PCS = D->
getAttr<PcsAttr>())
279 if (D->
hasAttr<AArch64VectorPcsAttr>())
282 if (D->
hasAttr<AArch64SVEPcsAttr>())
285 if (D->
hasAttr<DeviceKernelAttr>())
288 if (D->
hasAttr<IntelOclBiccAttr>())
297 if (D->
hasAttr<PreserveMostAttr>())
300 if (D->
hasAttr<PreserveAllAttr>())
306 if (D->
hasAttr<PreserveNoneAttr>())
309 if (D->
hasAttr<RISCVVectorCCAttr>())
312 if (RISCVVLSCCAttr *PCS = D->
getAttr<RISCVVLSCCAttr>()) {
313 switch (PCS->getVectorWidth()) {
315 llvm_unreachable(
"Invalid RISC-V VLS ABI VLEN");
316#define CC_VLS_CASE(ABI_VLEN) \
318 return CC_RISCVVLSCall_##ABI_VLEN;
353 return ::arrangeLLVMFunctionInfo(
354 *
this,
true, argTypes,
361 if (FD->
hasAttr<CUDAGlobalAttr>()) {
397 !Target.getCXXABI().hasConstructorVariants();
410 bool PassParams =
true;
412 if (
auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
415 if (
auto Inherited = CD->getInheritedConstructor())
427 if (!paramInfos.empty()) {
430 paramInfos.insert(paramInfos.begin() + 1, AddedArgs.
Prefix,
433 paramInfos.append(AddedArgs.
Suffix,
438 (PassParams && MD->isVariadic() ?
RequiredArgs(argTypes.size())
444 ? CGM.getContext().VoidPtrTy
447 argTypes, extInfo, paramInfos, required);
453 for (
auto &arg : args)
461 for (
auto &arg : args)
468 unsigned totalArgs) {
486 unsigned ExtraPrefixArgs,
unsigned ExtraSuffixArgs,
bool PassProtoArgs) {
488 for (
const auto &Arg : args)
489 ArgTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
492 unsigned TotalPrefixArgs = 1 + ExtraPrefixArgs;
497 FPT, TotalPrefixArgs + ExtraSuffixArgs)
503 ? CGM.getContext().VoidPtrTy
510 if (PassProtoArgs && FPT->hasExtParameterInfos()) {
517 ArgTypes, Info, ParamInfos,
Required);
526 if (MD->isImplicitObjectMemberFunction())
534 if (DeviceKernelAttr::isOpenCLSpelling(FD->
getAttr<DeviceKernelAttr>()) &&
537 CGM.getTargetCodeGenInfo().setOCLKernelStubCallingConvention(FT);
545 {}, noProto->getExtInfo(), {},
572 argTys.push_back(Context.getCanonicalParamType(receiverType));
574 argTys.push_back(Context.getCanonicalParamType(Context.getObjCSelType()));
576 argTys.push_back(Context.getCanonicalParamType(I->getType()));
578 I->hasAttr<NoEscapeAttr>());
579 extParamInfos.push_back(extParamInfo);
583 bool IsTargetDefaultMSABI =
589 if (
getContext().getLangOpts().ObjCAutoRefCount &&
590 MD->
hasAttr<NSReturnsRetainedAttr>())
627 assert(MD->
isVirtual() &&
"only methods have thunks");
644 ArgTys.push_back(*FTP->param_type_begin());
646 ArgTys.push_back(Context.IntTy);
647 CallingConv CC = Context.getDefaultCallingConvention(
659 unsigned numExtraRequiredArgs,
bool chainCall) {
660 assert(args.size() >= numExtraRequiredArgs);
670 if (proto->isVariadic())
673 if (proto->hasExtParameterInfos())
687 for (
const auto &arg : args)
692 paramInfos, required);
702 chainCall ? 1 : 0, chainCall);
731 for (
const auto &Arg : args)
732 argTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
772 assert(numPrefixArgs + 1 <= args.size() &&
773 "Emitting a call with less args than the required prefix?");
784 paramInfos, required);
795 assert(signature.
arg_size() <= args.size());
796 if (signature.
arg_size() == args.size())
801 if (!sigParamInfos.empty()) {
802 paramInfos.append(sigParamInfos.begin(), sigParamInfos.end());
803 paramInfos.resize(args.size());
835 assert(llvm::all_of(argTypes,
839 llvm::FoldingSetNodeID ID;
844 bool isDelegateCall =
847 info, paramInfos, required, resultType, argTypes);
849 void *insertPos =
nullptr;
850 CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, insertPos);
858 info, paramInfos, resultType, argTypes, required);
859 FunctionInfos.InsertNode(FI, insertPos);
861 bool inserted = FunctionsBeingProcessed.insert(FI).second;
863 assert(inserted &&
"Recursively being processed?");
866 if (CC == llvm::CallingConv::SPIR_KERNEL) {
873 CGM.getABIInfo().computeInfo(*FI);
884 if (I.info.canHaveCoerceToType() && I.info.getCoerceToType() ==
nullptr)
887 bool erased = FunctionsBeingProcessed.erase(FI);
889 assert(erased &&
"Not in set?");
895 bool chainCall,
bool delegateCall,
901 assert(paramInfos.empty() || paramInfos.size() == argTypes.size());
905 void *buffer =
operator new(totalSizeToAlloc<ArgInfo, ExtParameterInfo>(
906 argTypes.size() + 1, paramInfos.size()));
908 CGFunctionInfo *FI =
new (buffer) CGFunctionInfo();
909 FI->CallingConvention = llvmCC;
910 FI->EffectiveCallingConvention = llvmCC;
911 FI->ASTCallingConvention = info.
getCC();
912 FI->InstanceMethod = instanceMethod;
913 FI->ChainCall = chainCall;
914 FI->DelegateCall = delegateCall;
920 FI->Required = required;
923 FI->ArgStruct =
nullptr;
924 FI->ArgStructAlign = 0;
925 FI->NumArgs = argTypes.size();
926 FI->HasExtParameterInfos = !paramInfos.empty();
927 FI->getArgsBuffer()[0].
type = resultType;
928 FI->MaxVectorWidth = 0;
929 for (
unsigned i = 0, e = argTypes.size(); i != e; ++i)
930 FI->getArgsBuffer()[i + 1].
type = argTypes[i];
931 for (
unsigned i = 0, e = paramInfos.size(); i != e; ++i)
932 FI->getExtParameterInfosBuffer()[i] = paramInfos[i];
942struct TypeExpansion {
943 enum TypeExpansionKind {
955 const TypeExpansionKind Kind;
957 TypeExpansion(TypeExpansionKind K) : Kind(K) {}
958 virtual ~TypeExpansion() {}
961struct ConstantArrayExpansion : TypeExpansion {
965 ConstantArrayExpansion(QualType EltTy, uint64_t NumElts)
966 : TypeExpansion(TEK_ConstantArray), EltTy(EltTy), NumElts(NumElts) {}
967 static bool classof(
const TypeExpansion *TE) {
968 return TE->Kind == TEK_ConstantArray;
972struct RecordExpansion : TypeExpansion {
973 SmallVector<const CXXBaseSpecifier *, 1> Bases;
975 SmallVector<const FieldDecl *, 1> Fields;
977 RecordExpansion(SmallVector<const CXXBaseSpecifier *, 1> &&Bases,
978 SmallVector<const FieldDecl *, 1> &&Fields)
979 : TypeExpansion(TEK_Record), Bases(std::move(Bases)),
980 Fields(std::move(Fields)) {}
981 static bool classof(
const TypeExpansion *TE) {
982 return TE->Kind == TEK_Record;
986struct ComplexExpansion : TypeExpansion {
989 ComplexExpansion(QualType EltTy) : TypeExpansion(
TEK_Complex), EltTy(EltTy) {}
990 static bool classof(
const TypeExpansion *TE) {
995struct NoExpansion : TypeExpansion {
996 NoExpansion() : TypeExpansion(TEK_None) {}
997 static bool classof(
const TypeExpansion *TE) {
return TE->Kind == TEK_None; }
1001static std::unique_ptr<TypeExpansion>
1004 return std::make_unique<ConstantArrayExpansion>(AT->getElementType(),
1010 assert(!RD->hasFlexibleArrayMember() &&
1011 "Cannot expand structure with flexible array.");
1012 if (RD->isUnion()) {
1018 for (
const auto *FD : RD->fields()) {
1019 if (FD->isZeroLengthBitField())
1021 assert(!FD->isBitField() &&
1022 "Cannot expand structure with bit-field members.");
1023 CharUnits FieldSize = Context.getTypeSizeInChars(FD->getType());
1024 if (UnionSize < FieldSize) {
1025 UnionSize = FieldSize;
1030 Fields.push_back(LargestFD);
1032 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
1033 assert(!CXXRD->isDynamicClass() &&
1034 "cannot expand vtable pointers in dynamic classes");
1035 llvm::append_range(Bases, llvm::make_pointer_range(CXXRD->bases()));
1038 for (
const auto *FD : RD->fields()) {
1039 if (FD->isZeroLengthBitField())
1041 assert(!FD->isBitField() &&
1042 "Cannot expand structure with bit-field members.");
1043 Fields.push_back(FD);
1046 return std::make_unique<RecordExpansion>(std::move(Bases),
1050 return std::make_unique<ComplexExpansion>(CT->getElementType());
1052 return std::make_unique<NoExpansion>();
1057 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1060 if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1062 for (
auto BS : RExp->Bases)
1064 for (
auto FD : RExp->Fields)
1077 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1078 for (
int i = 0, n = CAExp->NumElts; i < n; i++) {
1081 }
else if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1082 for (
auto BS : RExp->Bases)
1084 for (
auto FD : RExp->Fields)
1086 }
else if (
auto CExp = dyn_cast<ComplexExpansion>(Exp.get())) {
1097 ConstantArrayExpansion *CAE,
1099 llvm::function_ref<
void(
Address)> Fn) {
1100 for (
int i = 0, n = CAE->NumElts; i < n; i++) {
1106void CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV,
1107 llvm::Function::arg_iterator &AI) {
1108 assert(LV.isSimple() &&
1109 "Unexpected non-simple lvalue during struct expansion.");
1112 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1114 *
this, CAExp, LV.getAddress(), [&](Address EltAddr) {
1115 LValue LV = MakeAddrLValue(EltAddr, CAExp->EltTy);
1116 ExpandTypeFromArgs(CAExp->EltTy, LV, AI);
1118 }
else if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1119 Address
This = LV.getAddress();
1120 for (
const CXXBaseSpecifier *BS : RExp->Bases) {
1124 false, SourceLocation());
1125 LValue SubLV = MakeAddrLValue(Base, BS->
getType());
1128 ExpandTypeFromArgs(BS->
getType(), SubLV, AI);
1130 for (
auto FD : RExp->Fields) {
1132 LValue SubLV = EmitLValueForFieldInitialization(LV, FD);
1133 ExpandTypeFromArgs(FD->getType(), SubLV, AI);
1136 auto realValue = &*AI++;
1137 auto imagValue = &*AI++;
1138 EmitStoreOfComplex(
ComplexPairTy(realValue, imagValue), LV,
true);
1143 llvm::Value *Arg = &*AI++;
1144 if (LV.isBitField()) {
1150 if (Arg->getType()->isPointerTy()) {
1151 Address
Addr = LV.getAddress();
1152 Arg = Builder.CreateBitCast(Arg,
Addr.getElementType());
1154 EmitStoreOfScalar(Arg, LV);
1159void CodeGenFunction::ExpandTypeToArgs(
1160 QualType Ty, CallArg Arg, llvm::FunctionType *IRFuncTy,
1161 SmallVectorImpl<llvm::Value *> &IRCallArgs,
unsigned &IRCallArgPos) {
1163 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1168 CallArg(convertTempToRValue(EltAddr, CAExp->EltTy, SourceLocation()),
1170 ExpandTypeToArgs(CAExp->EltTy, EltArg, IRFuncTy, IRCallArgs,
1173 }
else if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1176 for (
const CXXBaseSpecifier *BS : RExp->Bases) {
1180 false, SourceLocation());
1184 ExpandTypeToArgs(BS->
getType(), BaseArg, IRFuncTy, IRCallArgs,
1188 LValue LV = MakeAddrLValue(This, Ty);
1189 for (
auto FD : RExp->Fields) {
1191 CallArg(EmitRValueForField(LV, FD, SourceLocation()), FD->getType());
1192 ExpandTypeToArgs(FD->getType(), FldArg, IRFuncTy, IRCallArgs,
1197 IRCallArgs[IRCallArgPos++] = CV.first;
1198 IRCallArgs[IRCallArgPos++] = CV.second;
1202 assert(RV.isScalar() &&
1203 "Unexpected non-scalar rvalue during struct expansion.");
1206 llvm::Value *
V = RV.getScalarVal();
1207 if (IRCallArgPos < IRFuncTy->getNumParams() &&
1208 V->getType() != IRFuncTy->getParamType(IRCallArgPos))
1209 V = Builder.CreateBitCast(
V, IRFuncTy->getParamType(IRCallArgPos));
1211 IRCallArgs[IRCallArgPos++] =
V;
1219 const Twine &Name =
"tmp") {
1232 llvm::StructType *SrcSTy,
1236 if (SrcSTy->getNumElements() == 0)
1245 uint64_t FirstEltSize = CGF.
CGM.
getDataLayout().getTypeStoreSize(FirstElt);
1246 if (FirstEltSize < DstSize &&
1255 if (llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy))
1270 if (Val->getType() == Ty)
1276 return CGF.
Builder.CreateBitCast(Val, Ty,
"coerce.val");
1282 llvm::Type *DestIntTy = Ty;
1286 if (Val->getType() != DestIntTy) {
1288 if (DL.isBigEndian()) {
1291 uint64_t SrcSize = DL.getTypeSizeInBits(Val->getType());
1292 uint64_t DstSize = DL.getTypeSizeInBits(DestIntTy);
1294 if (SrcSize > DstSize) {
1295 Val = CGF.
Builder.CreateLShr(Val, SrcSize - DstSize,
"coerce.highbits");
1296 Val = CGF.
Builder.CreateTrunc(Val, DestIntTy,
"coerce.val.ii");
1298 Val = CGF.
Builder.CreateZExt(Val, DestIntTy,
"coerce.val.ii");
1299 Val = CGF.
Builder.CreateShl(Val, DstSize - SrcSize,
"coerce.highbits");
1303 Val = CGF.
Builder.CreateIntCast(Val, DestIntTy,
false,
"coerce.val.ii");
1308 Val = CGF.
Builder.CreateIntToPtr(Val, Ty,
"coerce.val.ip");
1329 if (llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy)) {
1331 DstSize.getFixedValue(), CGF);
1346 if (!SrcSize.isScalable() && !DstSize.isScalable() &&
1347 SrcSize.getFixedValue() >= DstSize.getFixedValue()) {
1361 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(Ty)) {
1362 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
1365 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
1366 FixedSrcTy->getElementType()->isIntegerTy(8)) {
1367 ScalableDstTy = llvm::ScalableVectorType::get(
1368 FixedSrcTy->getElementType(),
1370 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
1372 if (ScalableDstTy->getElementType() == FixedSrcTy->getElementType()) {
1374 auto *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
1375 llvm::Value *Result = CGF.
Builder.CreateInsertVector(
1376 ScalableDstTy, PoisonVec, Load, uint64_t(0),
"cast.scalable");
1378 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, Ty));
1379 if (Result->getType() != ScalableDstTy)
1380 Result = CGF.
Builder.CreateBitCast(Result, ScalableDstTy);
1381 if (Result->getType() != Ty)
1382 Result = CGF.
Builder.CreateExtractVector(Ty, Result, uint64_t(0));
1394 llvm::ConstantInt::get(CGF.
IntPtrTy, SrcSize.getKnownMinValue()));
1399 llvm::TypeSize DstSize,
1400 bool DstIsVolatile) {
1404 llvm::Type *SrcTy = Src->getType();
1405 llvm::TypeSize SrcSize =
CGM.getDataLayout().getTypeAllocSize(SrcTy);
1411 if (llvm::StructType *DstSTy =
1413 assert(!SrcSize.isScalable());
1415 SrcSize.getFixedValue(), *
this);
1419 if (SrcSize.isScalable() || SrcSize <= DstSize) {
1420 if (SrcTy->isIntegerTy() && Dst.
getElementType()->isPointerTy() &&
1424 auto *I =
Builder.CreateStore(Src, Dst, DstIsVolatile);
1426 }
else if (llvm::StructType *STy =
1427 dyn_cast<llvm::StructType>(Src->getType())) {
1430 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1432 llvm::Value *Elt =
Builder.CreateExtractValue(Src, i);
1433 auto *I =
Builder.CreateStore(Elt, EltPtr, DstIsVolatile);
1441 }
else if (SrcTy->isIntegerTy()) {
1443 llvm::Type *DstIntTy =
Builder.getIntNTy(DstSize.getFixedValue() * 8);
1460 Builder.CreateStore(Src, Tmp);
1461 auto *I =
Builder.CreateMemCpy(
1480static std::pair<llvm::Value *, bool>
1482 llvm::ScalableVectorType *FromTy, llvm::Value *
V,
1483 StringRef Name =
"") {
1486 if (FromTy->getElementType()->isIntegerTy(1) &&
1487 ToTy->getElementType() == CGF.
Builder.getInt8Ty()) {
1488 if (!FromTy->getElementCount().isKnownMultipleOf(8)) {
1489 FromTy = llvm::ScalableVectorType::get(
1490 FromTy->getElementType(),
1491 llvm::alignTo<8>(FromTy->getElementCount().getKnownMinValue()));
1492 llvm::Value *ZeroVec = llvm::Constant::getNullValue(FromTy);
1493 V = CGF.
Builder.CreateInsertVector(FromTy, ZeroVec,
V, uint64_t(0));
1495 FromTy = llvm::ScalableVectorType::get(
1496 ToTy->getElementType(),
1497 FromTy->getElementCount().getKnownMinValue() / 8);
1498 V = CGF.
Builder.CreateBitCast(
V, FromTy);
1500 if (FromTy->getElementType() == ToTy->getElementType()) {
1501 V->setName(Name +
".coerce");
1502 V = CGF.
Builder.CreateExtractVector(ToTy,
V, uint64_t(0),
"cast.fixed");
1512class ClangToLLVMArgMapping {
1513 static const unsigned InvalidIndex = ~0U;
1514 unsigned InallocaArgNo;
1516 unsigned TotalIRArgs;
1520 unsigned PaddingArgIndex;
1523 unsigned FirstArgIndex;
1524 unsigned NumberOfArgs;
1527 : PaddingArgIndex(InvalidIndex), FirstArgIndex(InvalidIndex),
1531 SmallVector<IRArgs, 8> ArgInfo;
1534 ClangToLLVMArgMapping(
const ASTContext &Context,
const CGFunctionInfo &FI,
1535 bool OnlyRequiredArgs =
false)
1536 : InallocaArgNo(InvalidIndex), SRetArgNo(InvalidIndex), TotalIRArgs(0),
1537 ArgInfo(OnlyRequiredArgs ? FI.getNumRequiredArgs() : FI.arg_size()) {
1538 construct(Context, FI, OnlyRequiredArgs);
1541 bool hasInallocaArg()
const {
return InallocaArgNo != InvalidIndex; }
1542 unsigned getInallocaArgNo()
const {
1543 assert(hasInallocaArg());
1544 return InallocaArgNo;
1547 bool hasSRetArg()
const {
return SRetArgNo != InvalidIndex; }
1548 unsigned getSRetArgNo()
const {
1549 assert(hasSRetArg());
1553 unsigned totalIRArgs()
const {
return TotalIRArgs; }
1555 bool hasPaddingArg(
unsigned ArgNo)
const {
1556 assert(ArgNo < ArgInfo.size());
1557 return ArgInfo[ArgNo].PaddingArgIndex != InvalidIndex;
1559 unsigned getPaddingArgNo(
unsigned ArgNo)
const {
1560 assert(hasPaddingArg(ArgNo));
1561 return ArgInfo[ArgNo].PaddingArgIndex;
1566 std::pair<unsigned, unsigned> getIRArgs(
unsigned ArgNo)
const {
1567 assert(ArgNo < ArgInfo.size());
1568 return std::make_pair(ArgInfo[ArgNo].FirstArgIndex,
1569 ArgInfo[ArgNo].NumberOfArgs);
1573 void construct(
const ASTContext &Context,
const CGFunctionInfo &FI,
1574 bool OnlyRequiredArgs);
1577void ClangToLLVMArgMapping::construct(
const ASTContext &Context,
1578 const CGFunctionInfo &FI,
1579 bool OnlyRequiredArgs) {
1580 unsigned IRArgNo = 0;
1581 bool SwapThisWithSRet =
false;
1586 SRetArgNo = SwapThisWithSRet ? 1 : IRArgNo++;
1594 QualType ArgType = I->type;
1595 const ABIArgInfo &AI = I->info;
1597 auto &IRArgs = ArgInfo[ArgNo];
1600 IRArgs.PaddingArgIndex = IRArgNo++;
1607 llvm::StructType *STy = dyn_cast<llvm::StructType>(AI.
getCoerceToType());
1609 IRArgs.NumberOfArgs = STy->getNumElements();
1611 IRArgs.NumberOfArgs = 1;
1617 IRArgs.NumberOfArgs = 1;
1622 IRArgs.NumberOfArgs = 0;
1632 if (IRArgs.NumberOfArgs > 0) {
1633 IRArgs.FirstArgIndex = IRArgNo;
1634 IRArgNo += IRArgs.NumberOfArgs;
1639 if (IRArgNo == 1 && SwapThisWithSRet)
1642 assert(ArgNo == ArgInfo.size());
1645 InallocaArgNo = IRArgNo++;
1647 TotalIRArgs = IRArgNo;
1655 return RI.
isIndirect() || (RI.isInAlloca() && RI.getInAllocaSRet());
1670 switch (BT->getKind()) {
1673 case BuiltinType::Float:
1675 case BuiltinType::Double:
1677 case BuiltinType::LongDouble:
1688 if (BT->getKind() == BuiltinType::LongDouble)
1689 return getTarget().useObjCFP2RetForComplexLongDouble();
1703 bool Inserted = FunctionsBeingProcessed.insert(&FI).second;
1705 assert(Inserted &&
"Recursively being processed?");
1707 llvm::Type *resultType =
nullptr;
1712 llvm_unreachable(
"Invalid ABI kind for return argument");
1724 unsigned addressSpace = CGM.getTypes().getTargetAddressSpace(ret);
1725 resultType = llvm::PointerType::get(
getLLVMContext(), addressSpace);
1741 ClangToLLVMArgMapping IRFunctionArgs(
getContext(), FI,
true);
1745 if (IRFunctionArgs.hasSRetArg()) {
1746 ArgTypes[IRFunctionArgs.getSRetArgNo()] = llvm::PointerType::get(
1751 if (IRFunctionArgs.hasInallocaArg())
1752 ArgTypes[IRFunctionArgs.getInallocaArgNo()] =
1759 for (; it != ie; ++it, ++ArgNo) {
1763 if (IRFunctionArgs.hasPaddingArg(ArgNo))
1764 ArgTypes[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
1767 unsigned FirstIRArg, NumIRArgs;
1768 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
1773 assert(NumIRArgs == 0);
1777 assert(NumIRArgs == 1);
1779 ArgTypes[FirstIRArg] = llvm::PointerType::get(
1783 assert(NumIRArgs == 1);
1784 ArgTypes[FirstIRArg] = llvm::PointerType::get(
1793 llvm::StructType *st = dyn_cast<llvm::StructType>(argType);
1795 assert(NumIRArgs == st->getNumElements());
1796 for (
unsigned i = 0, e = st->getNumElements(); i != e; ++i)
1797 ArgTypes[FirstIRArg + i] = st->getElementType(i);
1799 assert(NumIRArgs == 1);
1800 ArgTypes[FirstIRArg] = argType;
1806 auto ArgTypesIter = ArgTypes.begin() + FirstIRArg;
1808 *ArgTypesIter++ = EltTy;
1810 assert(ArgTypesIter == ArgTypes.begin() + FirstIRArg + NumIRArgs);
1815 auto ArgTypesIter = ArgTypes.begin() + FirstIRArg;
1817 assert(ArgTypesIter == ArgTypes.begin() + FirstIRArg + NumIRArgs);
1822 bool Erased = FunctionsBeingProcessed.erase(&FI);
1824 assert(Erased &&
"Not in set?");
1826 return llvm::FunctionType::get(resultType, ArgTypes, FI.
isVariadic());
1840 llvm::AttrBuilder &FuncAttrs,
1847 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
1851 FuncAttrs.addAttribute(
"aarch64_pstate_sm_enabled");
1853 FuncAttrs.addAttribute(
"aarch64_pstate_sm_compatible");
1855 FuncAttrs.addAttribute(
"aarch64_za_state_agnostic");
1859 FuncAttrs.addAttribute(
"aarch64_preserves_za");
1861 FuncAttrs.addAttribute(
"aarch64_in_za");
1863 FuncAttrs.addAttribute(
"aarch64_out_za");
1865 FuncAttrs.addAttribute(
"aarch64_inout_za");
1869 FuncAttrs.addAttribute(
"aarch64_preserves_zt0");
1871 FuncAttrs.addAttribute(
"aarch64_in_zt0");
1873 FuncAttrs.addAttribute(
"aarch64_out_zt0");
1875 FuncAttrs.addAttribute(
"aarch64_inout_zt0");
1879 const Decl *Callee) {
1885 for (
const OMPAssumeAttr *AA : Callee->specific_attrs<OMPAssumeAttr>())
1886 AA->getAssumption().split(Attrs,
",");
1889 FuncAttrs.addAttribute(llvm::AssumptionAttrKey,
1890 llvm::join(Attrs.begin(), Attrs.end(),
","));
1897 if (
const RecordType *RT =
1899 if (
const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl()))
1900 return ClassDecl->hasTrivialDestructor();
1906 const Decl *TargetDecl) {
1912 if (
Module.getLangOpts().Sanitize.has(SanitizerKind::Memory))
1916 if (!
Module.getLangOpts().CPlusPlus)
1919 if (
const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(TargetDecl)) {
1920 if (FDecl->isExternC())
1922 }
else if (
const VarDecl *VDecl = dyn_cast<VarDecl>(TargetDecl)) {
1924 if (VDecl->isExternC())
1932 return Module.getCodeGenOpts().StrictReturn ||
1933 !
Module.MayDropFunctionReturn(
Module.getContext(), RetTy) ||
1934 Module.getLangOpts().Sanitize.has(SanitizerKind::Return);
1941 llvm::DenormalMode FP32DenormalMode,
1942 llvm::AttrBuilder &FuncAttrs) {
1943 if (FPDenormalMode != llvm::DenormalMode::getDefault())
1944 FuncAttrs.addAttribute(
"denormal-fp-math", FPDenormalMode.str());
1946 if (FP32DenormalMode != FPDenormalMode && FP32DenormalMode.isValid())
1947 FuncAttrs.addAttribute(
"denormal-fp-math-f32", FP32DenormalMode.str());
1955 llvm::AttrBuilder &FuncAttrs) {
1961 StringRef Name,
bool HasOptnone,
const CodeGenOptions &CodeGenOpts,
1963 llvm::AttrBuilder &FuncAttrs) {
1966 if (CodeGenOpts.OptimizeSize)
1967 FuncAttrs.addAttribute(llvm::Attribute::OptimizeForSize);
1968 if (CodeGenOpts.OptimizeSize == 2)
1969 FuncAttrs.addAttribute(llvm::Attribute::MinSize);
1972 if (CodeGenOpts.DisableRedZone)
1973 FuncAttrs.addAttribute(llvm::Attribute::NoRedZone);
1974 if (CodeGenOpts.IndirectTlsSegRefs)
1975 FuncAttrs.addAttribute(
"indirect-tls-seg-refs");
1976 if (CodeGenOpts.NoImplicitFloat)
1977 FuncAttrs.addAttribute(llvm::Attribute::NoImplicitFloat);
1979 if (AttrOnCallSite) {
1984 FuncAttrs.addAttribute(llvm::Attribute::NoBuiltin);
1986 FuncAttrs.addAttribute(
"trap-func-name", CodeGenOpts.
TrapFuncName);
1988 switch (CodeGenOpts.getFramePointer()) {
1995 FuncAttrs.addAttribute(
"frame-pointer",
1997 CodeGenOpts.getFramePointer()));
2000 if (CodeGenOpts.LessPreciseFPMAD)
2001 FuncAttrs.addAttribute(
"less-precise-fpmad",
"true");
2003 if (CodeGenOpts.NullPointerIsValid)
2004 FuncAttrs.addAttribute(llvm::Attribute::NullPointerIsValid);
2007 FuncAttrs.addAttribute(
"no-trapping-math",
"true");
2011 if (LangOpts.NoHonorInfs)
2012 FuncAttrs.addAttribute(
"no-infs-fp-math",
"true");
2013 if (LangOpts.NoHonorNaNs)
2014 FuncAttrs.addAttribute(
"no-nans-fp-math",
"true");
2015 if (LangOpts.AllowFPReassoc && LangOpts.AllowRecip &&
2016 LangOpts.NoSignedZero && LangOpts.ApproxFunc &&
2017 (LangOpts.getDefaultFPContractMode() ==
2019 LangOpts.getDefaultFPContractMode() ==
2021 FuncAttrs.addAttribute(
"unsafe-fp-math",
"true");
2022 if (CodeGenOpts.SoftFloat)
2023 FuncAttrs.addAttribute(
"use-soft-float",
"true");
2024 FuncAttrs.addAttribute(
"stack-protector-buffer-size",
2025 llvm::utostr(CodeGenOpts.SSPBufferSize));
2026 if (LangOpts.NoSignedZero)
2027 FuncAttrs.addAttribute(
"no-signed-zeros-fp-math",
"true");
2030 const std::vector<std::string> &Recips = CodeGenOpts.
Reciprocals;
2031 if (!Recips.empty())
2032 FuncAttrs.addAttribute(
"reciprocal-estimates", llvm::join(Recips,
","));
2036 FuncAttrs.addAttribute(
"prefer-vector-width",
2039 if (CodeGenOpts.StackRealignment)
2040 FuncAttrs.addAttribute(
"stackrealign");
2041 if (CodeGenOpts.Backchain)
2042 FuncAttrs.addAttribute(
"backchain");
2043 if (CodeGenOpts.EnableSegmentedStacks)
2044 FuncAttrs.addAttribute(
"split-stack");
2046 if (CodeGenOpts.SpeculativeLoadHardening)
2047 FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
2050 switch (CodeGenOpts.getZeroCallUsedRegs()) {
2051 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Skip:
2052 FuncAttrs.removeAttribute(
"zero-call-used-regs");
2054 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPRArg:
2055 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used-gpr-arg");
2057 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPR:
2058 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used-gpr");
2060 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedArg:
2061 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used-arg");
2063 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Used:
2064 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used");
2066 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPRArg:
2067 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all-gpr-arg");
2069 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPR:
2070 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all-gpr");
2072 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllArg:
2073 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all-arg");
2075 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::All:
2076 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all");
2087 FuncAttrs.addAttribute(llvm::Attribute::Convergent);
2092 if ((LangOpts.CUDA && LangOpts.CUDAIsDevice) || LangOpts.OpenCL ||
2093 LangOpts.SYCLIsDevice) {
2094 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2097 if (CodeGenOpts.SaveRegParams && !AttrOnCallSite)
2098 FuncAttrs.addAttribute(
"save-reg-params");
2101 StringRef Var,
Value;
2103 FuncAttrs.addAttribute(Var,
Value);
2117 const llvm::Function &F,
2119 auto FFeatures = F.getFnAttribute(
"target-features");
2121 llvm::StringSet<> MergedNames;
2123 MergedFeatures.reserve(TargetOpts.
Features.size());
2125 auto AddUnmergedFeatures = [&](
auto &&FeatureRange) {
2126 for (StringRef
Feature : FeatureRange) {
2130 StringRef Name =
Feature.drop_front(1);
2131 bool Merged = !MergedNames.insert(Name).second;
2133 MergedFeatures.push_back(
Feature);
2137 if (FFeatures.isValid())
2138 AddUnmergedFeatures(llvm::split(FFeatures.getValueAsString(),
','));
2139 AddUnmergedFeatures(TargetOpts.
Features);
2141 if (!MergedFeatures.empty()) {
2142 llvm::sort(MergedFeatures);
2143 FuncAttr.addAttribute(
"target-features", llvm::join(MergedFeatures,
","));
2150 bool WillInternalize) {
2152 llvm::AttrBuilder FuncAttrs(F.getContext());
2155 if (!TargetOpts.
CPU.empty())
2156 FuncAttrs.addAttribute(
"target-cpu", TargetOpts.
CPU);
2157 if (!TargetOpts.
TuneCPU.empty())
2158 FuncAttrs.addAttribute(
"tune-cpu", TargetOpts.
TuneCPU);
2161 CodeGenOpts, LangOpts,
2164 if (!WillInternalize && F.isInterposable()) {
2169 F.addFnAttrs(FuncAttrs);
2173 llvm::AttributeMask AttrsToRemove;
2175 llvm::DenormalMode DenormModeToMerge = F.getDenormalModeRaw();
2176 llvm::DenormalMode DenormModeToMergeF32 = F.getDenormalModeF32Raw();
2177 llvm::DenormalMode Merged =
2181 if (DenormModeToMergeF32.isValid()) {
2186 if (Merged == llvm::DenormalMode::getDefault()) {
2187 AttrsToRemove.addAttribute(
"denormal-fp-math");
2188 }
else if (Merged != DenormModeToMerge) {
2190 FuncAttrs.addAttribute(
"denormal-fp-math",
2194 if (MergedF32 == llvm::DenormalMode::getDefault()) {
2195 AttrsToRemove.addAttribute(
"denormal-fp-math-f32");
2196 }
else if (MergedF32 != DenormModeToMergeF32) {
2198 FuncAttrs.addAttribute(
"denormal-fp-math-f32",
2202 F.removeFnAttrs(AttrsToRemove);
2207 F.addFnAttrs(FuncAttrs);
2210void CodeGenModule::getTrivialDefaultFunctionAttributes(
2211 StringRef Name,
bool HasOptnone,
bool AttrOnCallSite,
2212 llvm::AttrBuilder &FuncAttrs) {
2214 getLangOpts(), AttrOnCallSite,
2218void CodeGenModule::getDefaultFunctionAttributes(StringRef Name,
2220 bool AttrOnCallSite,
2221 llvm::AttrBuilder &FuncAttrs) {
2225 if (!AttrOnCallSite)
2231 if (!AttrOnCallSite)
2236 llvm::AttrBuilder &attrs) {
2237 getDefaultFunctionAttributes(
"",
false,
2239 GetCPUAndFeaturesAttributes(
GlobalDecl(), attrs);
2244 const NoBuiltinAttr *NBA =
nullptr) {
2245 auto AddNoBuiltinAttr = [&FuncAttrs](StringRef BuiltinName) {
2247 AttributeName +=
"no-builtin-";
2248 AttributeName += BuiltinName;
2249 FuncAttrs.addAttribute(AttributeName);
2253 if (LangOpts.NoBuiltin) {
2255 FuncAttrs.addAttribute(
"no-builtins");
2269 if (llvm::is_contained(NBA->builtinNames(),
"*")) {
2270 FuncAttrs.addAttribute(
"no-builtins");
2275 llvm::for_each(NBA->builtinNames(), AddNoBuiltinAttr);
2279 const llvm::DataLayout &DL,
const ABIArgInfo &AI,
2280 bool CheckCoerce =
true) {
2287 if (!DL.typeSizeEqualsStoreSize(Ty))
2294 if (llvm::TypeSize::isKnownGT(DL.getTypeSizeInBits(CoerceTy),
2295 DL.getTypeSizeInBits(Ty)))
2319 if (
const MatrixType *Matrix = dyn_cast<MatrixType>(QTy))
2321 if (
const ArrayType *Array = dyn_cast<ArrayType>(QTy))
2330 unsigned NumRequiredArgs,
unsigned ArgNo) {
2331 const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl);
2336 if (ArgNo >= NumRequiredArgs)
2340 if (ArgNo < FD->getNumParams()) {
2341 const ParmVarDecl *Param = FD->getParamDecl(ArgNo);
2342 if (Param && Param->hasAttr<MaybeUndefAttr>())
2359 if (llvm::AttributeFuncs::isNoFPClassCompatibleType(IRTy))
2362 if (llvm::StructType *ST = dyn_cast<llvm::StructType>(IRTy)) {
2364 llvm::all_of(ST->elements(),
2365 llvm::AttributeFuncs::isNoFPClassCompatibleType);
2373 llvm::FPClassTest Mask = llvm::fcNone;
2374 if (LangOpts.NoHonorInfs)
2375 Mask |= llvm::fcInf;
2376 if (LangOpts.NoHonorNaNs)
2377 Mask |= llvm::fcNan;
2383 llvm::AttributeList &Attrs) {
2384 if (Attrs.getMemoryEffects().getModRef() == llvm::ModRefInfo::NoModRef) {
2385 Attrs = Attrs.removeFnAttribute(
getLLVMContext(), llvm::Attribute::Memory);
2386 llvm::Attribute MemoryAttr = llvm::Attribute::getWithMemoryEffects(
2412 llvm::AttributeList &AttrList,
2414 bool AttrOnCallSite,
bool IsThunk) {
2422 FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2424 FuncAttrs.addAttribute(
"cmse_nonsecure_call");
2435 bool HasOptnone =
false;
2437 const NoBuiltinAttr *NBA =
nullptr;
2441 std::optional<llvm::Attribute::AttrKind> MemAttrForPtrArgs;
2442 bool AddedPotentialArgAccess =
false;
2443 auto AddPotentialArgAccess = [&]() {
2444 AddedPotentialArgAccess =
true;
2445 llvm::Attribute A = FuncAttrs.getAttribute(llvm::Attribute::Memory);
2447 FuncAttrs.addMemoryAttr(A.getMemoryEffects() |
2448 llvm::MemoryEffects::argMemOnly());
2455 if (TargetDecl->
hasAttr<ReturnsTwiceAttr>())
2456 FuncAttrs.addAttribute(llvm::Attribute::ReturnsTwice);
2457 if (TargetDecl->
hasAttr<NoThrowAttr>())
2458 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2459 if (TargetDecl->
hasAttr<NoReturnAttr>())
2460 FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2461 if (TargetDecl->
hasAttr<ColdAttr>())
2462 FuncAttrs.addAttribute(llvm::Attribute::Cold);
2463 if (TargetDecl->
hasAttr<HotAttr>())
2464 FuncAttrs.addAttribute(llvm::Attribute::Hot);
2465 if (TargetDecl->
hasAttr<NoDuplicateAttr>())
2466 FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate);
2467 if (TargetDecl->
hasAttr<ConvergentAttr>())
2468 FuncAttrs.addAttribute(llvm::Attribute::Convergent);
2470 if (
const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
2473 if (AttrOnCallSite && Fn->isReplaceableGlobalAllocationFunction()) {
2475 auto Kind = Fn->getDeclName().getCXXOverloadedOperator();
2477 (Kind == OO_New || Kind == OO_Array_New))
2478 RetAttrs.addAttribute(llvm::Attribute::NoAlias);
2481 const bool IsVirtualCall = MD && MD->
isVirtual();
2484 if (!(AttrOnCallSite && IsVirtualCall)) {
2485 if (Fn->isNoReturn())
2486 FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2487 NBA = Fn->getAttr<NoBuiltinAttr>();
2494 if (AttrOnCallSite && TargetDecl->
hasAttr<NoMergeAttr>())
2495 FuncAttrs.addAttribute(llvm::Attribute::NoMerge);
2499 if (TargetDecl->
hasAttr<ConstAttr>()) {
2500 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::none());
2501 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2504 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
2505 MemAttrForPtrArgs = llvm::Attribute::ReadNone;
2506 }
else if (TargetDecl->
hasAttr<PureAttr>()) {
2507 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
2508 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2510 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
2511 MemAttrForPtrArgs = llvm::Attribute::ReadOnly;
2512 }
else if (TargetDecl->
hasAttr<NoAliasAttr>()) {
2513 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::inaccessibleOrArgMemOnly());
2514 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2516 if (
const auto *RA = TargetDecl->
getAttr<RestrictAttr>();
2517 RA && RA->getDeallocator() ==
nullptr)
2518 RetAttrs.addAttribute(llvm::Attribute::NoAlias);
2519 if (TargetDecl->
hasAttr<ReturnsNonNullAttr>() &&
2520 !CodeGenOpts.NullPointerIsValid)
2521 RetAttrs.addAttribute(llvm::Attribute::NonNull);
2522 if (TargetDecl->
hasAttr<AnyX86NoCallerSavedRegistersAttr>())
2523 FuncAttrs.addAttribute(
"no_caller_saved_registers");
2524 if (TargetDecl->
hasAttr<AnyX86NoCfCheckAttr>())
2525 FuncAttrs.addAttribute(llvm::Attribute::NoCfCheck);
2526 if (TargetDecl->
hasAttr<LeafAttr>())
2527 FuncAttrs.addAttribute(llvm::Attribute::NoCallback);
2528 if (TargetDecl->
hasAttr<BPFFastCallAttr>())
2529 FuncAttrs.addAttribute(
"bpf_fastcall");
2531 HasOptnone = TargetDecl->
hasAttr<OptimizeNoneAttr>();
2532 if (
auto *AllocSize = TargetDecl->
getAttr<AllocSizeAttr>()) {
2533 std::optional<unsigned> NumElemsParam;
2534 if (AllocSize->getNumElemsParam().isValid())
2535 NumElemsParam = AllocSize->getNumElemsParam().getLLVMIndex();
2536 FuncAttrs.addAllocSizeAttr(AllocSize->getElemSizeParam().getLLVMIndex(),
2540 if (DeviceKernelAttr::isOpenCLSpelling(
2541 TargetDecl->
getAttr<DeviceKernelAttr>()) &&
2548 FuncAttrs.addAttribute(
"uniform-work-group-size",
"true");
2555 FuncAttrs.addAttribute(
2556 "uniform-work-group-size",
2557 llvm::toStringRef(
getLangOpts().OffloadUniformBlock));
2561 if (TargetDecl->
hasAttr<CUDAGlobalAttr>() &&
2563 FuncAttrs.addAttribute(
"uniform-work-group-size",
"true");
2565 if (TargetDecl->
hasAttr<ArmLocallyStreamingAttr>())
2566 FuncAttrs.addAttribute(
"aarch64_pstate_sm_body");
2578 getDefaultFunctionAttributes(Name, HasOptnone, AttrOnCallSite, FuncAttrs);
2583 if (TargetDecl->
hasAttr<NoSpeculativeLoadHardeningAttr>())
2584 FuncAttrs.removeAttribute(llvm::Attribute::SpeculativeLoadHardening);
2585 if (TargetDecl->
hasAttr<SpeculativeLoadHardeningAttr>())
2586 FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
2587 if (TargetDecl->
hasAttr<NoSplitStackAttr>())
2588 FuncAttrs.removeAttribute(
"split-stack");
2589 if (TargetDecl->
hasAttr<ZeroCallUsedRegsAttr>()) {
2592 TargetDecl->
getAttr<ZeroCallUsedRegsAttr>()->getZeroCallUsedRegs();
2593 FuncAttrs.removeAttribute(
"zero-call-used-regs");
2594 FuncAttrs.addAttribute(
2595 "zero-call-used-regs",
2596 ZeroCallUsedRegsAttr::ConvertZeroCallUsedRegsKindToStr(Kind));
2603 if (CodeGenOpts.NoPLT) {
2604 if (
auto *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
2605 if (!Fn->isDefined() && !AttrOnCallSite) {
2606 FuncAttrs.addAttribute(llvm::Attribute::NonLazyBind);
2611 if (TargetDecl->
hasAttr<NoConvergentAttr>())
2612 FuncAttrs.removeAttribute(llvm::Attribute::Convergent);
2617 if (TargetDecl && CodeGenOpts.UniqueInternalLinkageNames) {
2618 if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
2619 if (!FD->isExternallyVisible())
2620 FuncAttrs.addAttribute(
"sample-profile-suffix-elision-policy",
2627 if (!AttrOnCallSite) {
2628 if (TargetDecl && TargetDecl->
hasAttr<CmseNSEntryAttr>())
2629 FuncAttrs.addAttribute(
"cmse_nonsecure_entry");
2632 auto shouldDisableTailCalls = [&] {
2634 if (CodeGenOpts.DisableTailCalls)
2640 if (TargetDecl->
hasAttr<DisableTailCallsAttr>() ||
2641 TargetDecl->
hasAttr<AnyX86InterruptAttr>())
2644 if (CodeGenOpts.NoEscapingBlockTailCalls) {
2645 if (
const auto *BD = dyn_cast<BlockDecl>(TargetDecl))
2646 if (!BD->doesNotEscape())
2652 if (shouldDisableTailCalls())
2653 FuncAttrs.addAttribute(
"disable-tail-calls",
"true");
2658 static const llvm::StringSet<> ReturnsTwiceFn{
2659 "_setjmpex",
"setjmp",
"_setjmp",
"vfork",
2660 "sigsetjmp",
"__sigsetjmp",
"savectx",
"getcontext"};
2661 if (ReturnsTwiceFn.contains(Name))
2662 FuncAttrs.addAttribute(llvm::Attribute::ReturnsTwice);
2666 GetCPUAndFeaturesAttributes(CalleeInfo.
getCalleeDecl(), FuncAttrs);
2669 if (!MSHotPatchFunctions.empty()) {
2670 bool IsHotPatched = llvm::binary_search(MSHotPatchFunctions, Name);
2672 FuncAttrs.addAttribute(
"marked_for_windows_hot_patching");
2677 if (CodeGenOpts.isLoaderReplaceableFunctionName(Name))
2678 FuncAttrs.addAttribute(
"loader-replaceable");
2681 ClangToLLVMArgMapping IRFunctionArgs(
getContext(), FI);
2688 if (CodeGenOpts.EnableNoundefAttrs &&
2692 RetAttrs.addAttribute(llvm::Attribute::NoUndef);
2698 RetAttrs.addAttribute(llvm::Attribute::SExt);
2700 RetAttrs.addAttribute(llvm::Attribute::ZExt);
2702 RetAttrs.addAttribute(llvm::Attribute::NoExt);
2707 RetAttrs.addAttribute(llvm::Attribute::InReg);
2719 AddPotentialArgAccess();
2728 llvm_unreachable(
"Invalid ABI kind for return argument");
2736 RetAttrs.addDereferenceableAttr(
2738 if (
getTypes().getTargetAddressSpace(PTy) == 0 &&
2739 !CodeGenOpts.NullPointerIsValid)
2740 RetAttrs.addAttribute(llvm::Attribute::NonNull);
2742 llvm::Align Alignment =
2744 RetAttrs.addAlignmentAttr(Alignment);
2749 bool hasUsedSRet =
false;
2753 if (IRFunctionArgs.hasSRetArg()) {
2755 SRETAttrs.addStructRetAttr(
getTypes().ConvertTypeForMem(RetTy));
2756 SRETAttrs.addAttribute(llvm::Attribute::Writable);
2757 SRETAttrs.addAttribute(llvm::Attribute::DeadOnUnwind);
2760 SRETAttrs.addAttribute(llvm::Attribute::InReg);
2762 ArgAttrs[IRFunctionArgs.getSRetArgNo()] =
2767 if (IRFunctionArgs.hasInallocaArg()) {
2770 ArgAttrs[IRFunctionArgs.getInallocaArgNo()] =
2779 auto IRArgs = IRFunctionArgs.getIRArgs(0);
2781 assert(IRArgs.second == 1 &&
"Expected only a single `this` pointer.");
2787 if (!CodeGenOpts.NullPointerIsValid &&
2789 Attrs.addAttribute(llvm::Attribute::NonNull);
2796 Attrs.addDereferenceableOrNullAttr(
2802 llvm::Align Alignment =
2806 Attrs.addAlignmentAttr(Alignment);
2808 ArgAttrs[IRArgs.first] = llvm::AttributeSet::get(
getLLVMContext(), Attrs);
2813 I != E; ++I, ++ArgNo) {
2819 if (IRFunctionArgs.hasPaddingArg(ArgNo)) {
2821 ArgAttrs[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
2824 .addAttribute(llvm::Attribute::InReg));
2829 if (CodeGenOpts.EnableNoundefAttrs &&
2831 Attrs.addAttribute(llvm::Attribute::NoUndef);
2840 Attrs.addAttribute(llvm::Attribute::SExt);
2842 Attrs.addAttribute(llvm::Attribute::ZExt);
2844 Attrs.addAttribute(llvm::Attribute::NoExt);
2849 Attrs.addAttribute(llvm::Attribute::Nest);
2851 Attrs.addAttribute(llvm::Attribute::InReg);
2852 Attrs.addStackAlignmentAttr(llvm::MaybeAlign(AI.
getDirectAlign()));
2859 Attrs.addAttribute(llvm::Attribute::InReg);
2871 Attrs.addByValAttr(
getTypes().ConvertTypeForMem(ParamType));
2879 Attrs.addAttribute(llvm::Attribute::DeadOnReturn);
2884 if (CodeGenOpts.PassByValueIsNoAlias &&
Decl &&
2885 Decl->getArgPassingRestrictions() ==
2889 Attrs.addAttribute(llvm::Attribute::NoAlias);
2914 AddPotentialArgAccess();
2919 Attrs.addByRefAttr(
getTypes().ConvertTypeForMem(ParamType));
2930 AddPotentialArgAccess();
2938 if (
getTypes().getTargetAddressSpace(PTy) == 0 &&
2939 !CodeGenOpts.NullPointerIsValid)
2940 Attrs.addAttribute(llvm::Attribute::NonNull);
2942 llvm::Align Alignment =
2944 Attrs.addAlignmentAttr(Alignment);
2953 DeviceKernelAttr::isOpenCLSpelling(
2954 TargetDecl->
getAttr<DeviceKernelAttr>()) &&
2958 llvm::Align Alignment =
2960 Attrs.addAlignmentAttr(Alignment);
2967 Attrs.addAttribute(llvm::Attribute::NoAlias);
2976 Attrs.addStructRetAttr(
getTypes().ConvertTypeForMem(ParamType));
2981 Attrs.addAttribute(llvm::Attribute::NoAlias);
2985 if (!PTy->isIncompleteType() && PTy->isConstantSizeType()) {
2986 auto info =
getContext().getTypeInfoInChars(PTy);
2987 Attrs.addDereferenceableAttr(info.Width.getQuantity());
2988 Attrs.addAlignmentAttr(info.Align.getAsAlign());
2994 Attrs.addAttribute(llvm::Attribute::SwiftError);
2998 Attrs.addAttribute(llvm::Attribute::SwiftSelf);
3002 Attrs.addAttribute(llvm::Attribute::SwiftAsync);
3007 Attrs.addCapturesAttr(llvm::CaptureInfo::none());
3009 if (Attrs.hasAttributes()) {
3010 unsigned FirstIRArg, NumIRArgs;
3011 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
3012 for (
unsigned i = 0; i < NumIRArgs; i++)
3013 ArgAttrs[FirstIRArg + i] = ArgAttrs[FirstIRArg + i].addAttributes(
3020 if (AddedPotentialArgAccess && MemAttrForPtrArgs) {
3025 I != E; ++I, ++ArgNo) {
3026 if (I->info.isDirect() || I->info.isExpand() ||
3027 I->info.isCoerceAndExpand()) {
3028 unsigned FirstIRArg, NumIRArgs;
3029 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
3030 for (
unsigned i = FirstIRArg; i < FirstIRArg + NumIRArgs; ++i) {
3040 AttrList = llvm::AttributeList::get(
3049 llvm::Value *value) {
3050 llvm::Type *varType = CGF.
ConvertType(var->getType());
3054 if (value->getType() == varType)
3057 assert((varType->isIntegerTy() || varType->isFloatingPointTy()) &&
3058 "unexpected promotion type");
3061 return CGF.
Builder.CreateTrunc(value, varType,
"arg.unpromote");
3063 return CGF.
Builder.CreateFPCast(value, varType,
"arg.unpromote");
3069 QualType ArgType,
unsigned ArgNo) {
3077 if (!ArgType->isAnyPointerType() && !ArgType->isBlockPointerType())
3081 if (
auto ParmNNAttr = PVD->
getAttr<NonNullAttr>())
3088 if (NNAttr->isNonNull(ArgNo))
3095struct CopyBackSwiftError final : EHScopeStack::Cleanup {
3098 CopyBackSwiftError(Address temp, Address arg) : Temp(temp), Arg(
arg) {}
3099 void Emit(CodeGenFunction &CGF, Flags flags)
override {
3118 if (FD->hasImplicitReturnZero()) {
3119 QualType RetTy = FD->getReturnType().getUnqualifiedType();
3120 llvm::Type *LLVMTy =
CGM.getTypes().ConvertType(RetTy);
3121 llvm::Constant *
Zero = llvm::Constant::getNullValue(LLVMTy);
3129 ClangToLLVMArgMapping IRFunctionArgs(
CGM.getContext(), FI);
3130 assert(Fn->arg_size() == IRFunctionArgs.totalIRArgs());
3135 if (IRFunctionArgs.hasInallocaArg())
3136 ArgStruct =
Address(Fn->getArg(IRFunctionArgs.getInallocaArgNo()),
3140 if (IRFunctionArgs.hasSRetArg()) {
3141 auto AI = Fn->getArg(IRFunctionArgs.getSRetArgNo());
3142 AI->setName(
"agg.result");
3143 AI->addAttr(llvm::Attribute::NoAlias);
3150 ArgVals.reserve(Args.size());
3156 assert(FI.
arg_size() == Args.size() &&
3157 "Mismatch between function signature & arguments.");
3160 for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); i != e;
3161 ++i, ++info_it, ++ArgNo) {
3174 unsigned FirstIRArg, NumIRArgs;
3175 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
3179 assert(NumIRArgs == 0);
3192 assert(NumIRArgs == 1);
3215 llvm::ConstantInt::get(
IntPtrTy, Size.getQuantity()));
3216 ParamAddr = AlignedTemp;
3233 auto AI = Fn->getArg(FirstIRArg);
3241 assert(NumIRArgs == 1);
3243 if (
const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(Arg)) {
3246 PVD->getFunctionScopeIndex()) &&
3247 !
CGM.getCodeGenOpts().NullPointerIsValid)
3248 AI->addAttr(llvm::Attribute::NonNull);
3250 QualType OTy = PVD->getOriginalType();
3251 if (
const auto *ArrTy =
getContext().getAsConstantArrayType(OTy)) {
3257 QualType ETy = ArrTy->getElementType();
3258 llvm::Align Alignment =
3259 CGM.getNaturalTypeAlignment(ETy).getAsAlign();
3261 .addAlignmentAttr(Alignment));
3262 uint64_t ArrSize = ArrTy->getZExtSize();
3266 Attrs.addDereferenceableAttr(
3267 getContext().getTypeSizeInChars(ETy).getQuantity() *
3269 AI->addAttrs(Attrs);
3270 }
else if (
getContext().getTargetInfo().getNullPointerValue(
3272 !
CGM.getCodeGenOpts().NullPointerIsValid) {
3273 AI->addAttr(llvm::Attribute::NonNull);
3276 }
else if (
const auto *ArrTy =
3282 QualType ETy = ArrTy->getElementType();
3283 llvm::Align Alignment =
3284 CGM.getNaturalTypeAlignment(ETy).getAsAlign();
3286 .addAlignmentAttr(Alignment));
3287 if (!
getTypes().getTargetAddressSpace(ETy) &&
3288 !
CGM.getCodeGenOpts().NullPointerIsValid)
3289 AI->addAttr(llvm::Attribute::NonNull);
3294 const auto *AVAttr = PVD->getAttr<AlignValueAttr>();
3297 AVAttr = TOTy->getDecl()->getAttr<AlignValueAttr>();
3298 if (AVAttr && !
SanOpts.has(SanitizerKind::Alignment)) {
3302 llvm::ConstantInt *AlignmentCI =
3304 uint64_t AlignmentInt =
3305 AlignmentCI->getLimitedValue(llvm::Value::MaximumAlignment);
3306 if (AI->getParamAlign().valueOrOne() < AlignmentInt) {
3307 AI->removeAttr(llvm::Attribute::AttrKind::Alignment);
3309 .addAlignmentAttr(llvm::Align(AlignmentInt)));
3316 AI->addAttr(llvm::Attribute::NoAlias);
3324 assert(NumIRArgs == 1);
3328 llvm::Value *
V = AI;
3336 V, pointeeTy,
getContext().getTypeAlignInChars(pointeeTy));
3337 llvm::Value *incomingErrorValue =
Builder.CreateLoad(arg);
3338 Builder.CreateStore(incomingErrorValue, temp);
3359 if (
V->getType() != LTy)
3370 if (
auto *VecTyTo = dyn_cast<llvm::FixedVectorType>(
ConvertType(Ty))) {
3371 llvm::Value *ArgVal = Fn->getArg(FirstIRArg);
3372 if (
auto *VecTyFrom =
3373 dyn_cast<llvm::ScalableVectorType>(ArgVal->getType())) {
3375 *
this, VecTyTo, VecTyFrom, ArgVal, Arg->
getName());
3377 assert(NumIRArgs == 1);
3384 llvm::StructType *STy =
3395 STy->getNumElements() > 1) {
3396 llvm::TypeSize StructSize =
CGM.getDataLayout().getTypeAllocSize(STy);
3397 llvm::TypeSize PtrElementSize =
3399 if (StructSize.isScalable()) {
3400 assert(STy->containsHomogeneousScalableVectorTypes() &&
3401 "ABI only supports structure with homogeneous scalable vector "
3403 assert(StructSize == PtrElementSize &&
3404 "Only allow non-fractional movement of structure with"
3405 "homogeneous scalable vector type");
3406 assert(STy->getNumElements() == NumIRArgs);
3408 llvm::Value *LoadedStructValue = llvm::PoisonValue::get(STy);
3409 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
3410 auto *AI = Fn->getArg(FirstIRArg + i);
3411 AI->setName(Arg->
getName() +
".coerce" + Twine(i));
3413 Builder.CreateInsertValue(LoadedStructValue, AI, i);
3416 Builder.CreateStore(LoadedStructValue, Ptr);
3418 uint64_t SrcSize = StructSize.getFixedValue();
3419 uint64_t DstSize = PtrElementSize.getFixedValue();
3422 if (SrcSize <= DstSize) {
3429 assert(STy->getNumElements() == NumIRArgs);
3430 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
3431 auto AI = Fn->getArg(FirstIRArg + i);
3432 AI->setName(Arg->
getName() +
".coerce" + Twine(i));
3434 Builder.CreateStore(AI, EltPtr);
3437 if (SrcSize > DstSize) {
3438 Builder.CreateMemCpy(Ptr, AddrToStoreInto, DstSize);
3443 assert(NumIRArgs == 1);
3444 auto AI = Fn->getArg(FirstIRArg);
3445 AI->setName(Arg->
getName() +
".coerce");
3448 llvm::TypeSize::getFixed(
3449 getContext().getTypeSizeInChars(Ty).getQuantity() -
3474 auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
3478 unsigned argIndex = FirstIRArg;
3479 unsigned unpaddedIndex = 0;
3480 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
3481 llvm::Type *eltType = coercionType->getElementType(i);
3485 auto eltAddr =
Builder.CreateStructGEP(alloca, i);
3486 llvm::Value *elt = Fn->getArg(argIndex++);
3488 auto paramType = unpaddedStruct
3489 ? unpaddedStruct->getElementType(unpaddedIndex++)
3490 : unpaddedCoercionType;
3492 if (
auto *VecTyTo = dyn_cast<llvm::FixedVectorType>(eltType)) {
3493 if (
auto *VecTyFrom = dyn_cast<llvm::ScalableVectorType>(paramType)) {
3496 *
this, VecTyTo, VecTyFrom, elt, elt->getName());
3497 assert(Extracted &&
"Unexpected scalable to fixed vector coercion");
3500 Builder.CreateStore(elt, eltAddr);
3502 assert(argIndex == FirstIRArg + NumIRArgs);
3514 auto FnArgIter = Fn->arg_begin() + FirstIRArg;
3515 ExpandTypeFromArgs(Ty, LV, FnArgIter);
3516 assert(FnArgIter == Fn->arg_begin() + FirstIRArg + NumIRArgs);
3517 for (
unsigned i = 0, e = NumIRArgs; i != e; ++i) {
3518 auto AI = Fn->getArg(FirstIRArg + i);
3519 AI->setName(Arg->
getName() +
"." + Twine(i));
3525 auto *AI = Fn->getArg(FirstIRArg);
3526 AI->setName(Arg->
getName() +
".target_coerce");
3530 CGM.getABIInfo().createCoercedStore(AI, Ptr, ArgI,
false, *
this);
3544 assert(NumIRArgs == 0);
3556 if (
getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) {
3557 for (
int I = Args.size() - 1; I >= 0; --I)
3560 for (
unsigned I = 0, E = Args.size(); I != E; ++I)
3566 while (insn->use_empty()) {
3567 llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(insn);
3573 bitcast->eraseFromParent();
3579 llvm::Value *result) {
3581 llvm::BasicBlock *BB = CGF.
Builder.GetInsertBlock();
3584 if (&BB->back() != result)
3587 llvm::Type *resultType = result->getType();
3596 while (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(generator)) {
3602 if (generator->getNextNode() != bitcast)
3605 InstsToKill.push_back(bitcast);
3612 llvm::CallInst *call = dyn_cast<llvm::CallInst>(generator);
3616 bool doRetainAutorelease;
3619 doRetainAutorelease =
true;
3620 }
else if (call->getCalledOperand() ==
3622 doRetainAutorelease =
false;
3630 llvm::Instruction *prev = call->getPrevNode();
3633 prev = prev->getPrevNode();
3639 InstsToKill.push_back(prev);
3645 result = call->getArgOperand(0);
3646 InstsToKill.push_back(call);
3650 while (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(result)) {
3651 if (!bitcast->hasOneUse())
3653 InstsToKill.push_back(bitcast);
3654 result = bitcast->getOperand(0);
3658 for (
auto *I : InstsToKill)
3659 I->eraseFromParent();
3662 if (doRetainAutorelease)
3666 return CGF.
Builder.CreateBitCast(result, resultType);
3671 llvm::Value *result) {
3674 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurCodeDecl);
3683 llvm::CallInst *retainCall = dyn_cast<llvm::CallInst>(result);
3684 if (!retainCall || retainCall->getCalledOperand() !=
3689 llvm::Value *retainedValue = retainCall->getArgOperand(0);
3690 llvm::LoadInst *load =
3691 dyn_cast<llvm::LoadInst>(retainedValue->stripPointerCasts());
3692 if (!load || load->isAtomic() || load->isVolatile() ||
3699 llvm::Type *resultType = result->getType();
3701 assert(retainCall->use_empty());
3702 retainCall->eraseFromParent();
3705 return CGF.
Builder.CreateBitCast(load, resultType);
3712 llvm::Value *result) {
3735 auto GetStoreIfValid = [&CGF,
3736 ReturnValuePtr](llvm::User *
U) -> llvm::StoreInst * {
3737 auto *SI = dyn_cast<llvm::StoreInst>(
U);
3738 if (!SI || SI->getPointerOperand() != ReturnValuePtr ||
3744 assert(!SI->isAtomic() &&
3752 if (!ReturnValuePtr->hasOneUse()) {
3753 llvm::BasicBlock *IP = CGF.
Builder.GetInsertBlock();
3759 const llvm::Instruction *LoadIntoFakeUse =
nullptr;
3760 for (llvm::Instruction &I : llvm::reverse(*IP)) {
3764 if (LoadIntoFakeUse == &I)
3768 if (
auto *II = dyn_cast<llvm::IntrinsicInst>(&I)) {
3769 if (II->getIntrinsicID() == llvm::Intrinsic::lifetime_end)
3772 if (II->getIntrinsicID() == llvm::Intrinsic::fake_use) {
3773 LoadIntoFakeUse = dyn_cast<llvm::Instruction>(II->getArgOperand(0));
3777 return GetStoreIfValid(&I);
3782 llvm::StoreInst *store = GetStoreIfValid(ReturnValuePtr->user_back());
3788 llvm::BasicBlock *StoreBB = store->getParent();
3789 llvm::BasicBlock *IP = CGF.
Builder.GetInsertBlock();
3791 while (IP != StoreBB) {
3792 if (!SeenBBs.insert(IP).second || !(IP = IP->getSinglePredecessor()))
3808 int BitWidth,
int CharWidth) {
3809 assert(CharWidth <= 64);
3810 assert(
static_cast<unsigned>(BitWidth) <= Bits.size() * CharWidth);
3813 if (BitOffset >= CharWidth) {
3814 Pos += BitOffset / CharWidth;
3815 BitOffset = BitOffset % CharWidth;
3818 const uint64_t
Used = (uint64_t(1) << CharWidth) - 1;
3819 if (BitOffset + BitWidth >= CharWidth) {
3820 Bits[Pos++] |= (
Used << BitOffset) &
Used;
3821 BitWidth -= CharWidth - BitOffset;
3825 while (BitWidth >= CharWidth) {
3827 BitWidth -= CharWidth;
3831 Bits[Pos++] |= (
Used >> (CharWidth - BitWidth)) << BitOffset;
3839 int StorageSize,
int BitOffset,
int BitWidth,
3840 int CharWidth,
bool BigEndian) {
3843 setBitRange(TmpBits, BitOffset, BitWidth, CharWidth);
3846 std::reverse(TmpBits.begin(), TmpBits.end());
3848 for (uint64_t
V : TmpBits)
3849 Bits[StorageOffset++] |=
V;
3852static void setUsedBits(CodeGenModule &, QualType,
int,
3853 SmallVectorImpl<uint64_t> &);
3864 const RecordDecl *RD = RTy->getOriginalDecl()->getDefinition();
3895 QualType ETy = Context.getBaseElementType(ATy);
3896 int Size = Context.getTypeSizeInChars(ETy).getQuantity();
3900 for (
int I = 0, N = Context.getConstantArrayElementCount(ATy); I < N; ++I) {
3901 auto Src = TmpBits.begin();
3902 auto Dst = Bits.begin() + Offset + I * Size;
3903 for (
int J = 0; J < Size; ++J)
3916 if (
const auto *ATy = Context.getAsConstantArrayType(QTy))
3919 int Size = Context.getTypeSizeInChars(QTy).getQuantity();
3923 std::fill_n(Bits.begin() + Offset, Size,
3924 (uint64_t(1) << Context.getCharWidth()) - 1);
3928 int Pos,
int Size,
int CharWidth,
3933 for (
auto P = Bits.begin() + Pos, E = Bits.begin() + Pos + Size; P != E;
3935 Mask = (Mask << CharWidth) | *P;
3937 auto P = Bits.begin() + Pos + Size, End = Bits.begin() + Pos;
3939 Mask = (Mask << CharWidth) | *--P;
3948 llvm::IntegerType *ITy,
3950 assert(Src->getType() == ITy);
3951 assert(ITy->getScalarSizeInBits() <= 64);
3953 const llvm::DataLayout &DataLayout =
CGM.getDataLayout();
3954 int Size = DataLayout.getTypeStoreSize(ITy);
3958 int CharWidth =
CGM.getContext().getCharWidth();
3962 return Builder.CreateAnd(Src, Mask,
"cmse.clear");
3968 llvm::ArrayType *ATy,
3970 const llvm::DataLayout &DataLayout =
CGM.getDataLayout();
3971 int Size = DataLayout.getTypeStoreSize(ATy);
3976 int CharWidth =
CGM.getContext().getCharWidth();
3978 ATy->getArrayElementType()->getScalarSizeInBits() / CharWidth;
3980 llvm::Value *R = llvm::PoisonValue::get(ATy);
3981 for (
int I = 0, N = ATy->getArrayNumElements(); I != N; ++I) {
3983 DataLayout.isBigEndian());
3984 MaskIndex += CharsPerElt;
3985 llvm::Value *T0 =
Builder.CreateExtractValue(Src, I);
3986 llvm::Value *T1 =
Builder.CreateAnd(T0, Mask,
"cmse.clear");
3987 R =
Builder.CreateInsertValue(R, T1, I);
3995 uint64_t RetKeyInstructionsSourceAtom) {
4010 auto *I =
Builder.CreateRetVoid();
4011 if (RetKeyInstructionsSourceAtom)
4018 llvm::DebugLoc RetDbgLoc;
4019 llvm::Value *RV =
nullptr;
4029 llvm::Function::arg_iterator EI =
CurFn->arg_end();
4031 llvm::Value *ArgStruct = &*EI;
4032 llvm::Value *SRet =
Builder.CreateStructGEP(
4041 auto AI =
CurFn->arg_begin();
4059 CGM.getNaturalTypeAlignment(RetTy, &BaseInfo, &TBAAInfo);
4086 RetDbgLoc = SI->getDebugLoc();
4088 RV = SI->getValueOperand();
4089 SI->eraseFromParent();
4112 if (
auto *FD = dyn_cast<FunctionDecl>(
CurCodeDecl))
4113 RT = FD->getReturnType();
4114 else if (
auto *MD = dyn_cast<ObjCMethodDecl>(
CurCodeDecl))
4115 RT = MD->getReturnType();
4117 RT =
BlockInfo->BlockExpression->getFunctionType()->getReturnType();
4119 llvm_unreachable(
"Unexpected function/method type");
4135 auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
4140 unsigned unpaddedIndex = 0;
4141 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
4142 auto coercedEltType = coercionType->getElementType(i);
4146 auto eltAddr =
Builder.CreateStructGEP(addr, i);
4149 unpaddedStruct ? unpaddedStruct->getElementType(unpaddedIndex++)
4150 : unpaddedCoercionType,
4152 results.push_back(elt);
4156 if (results.size() == 1) {
4164 RV = llvm::PoisonValue::get(returnType);
4165 for (
unsigned i = 0, e = results.size(); i != e; ++i) {
4166 RV =
Builder.CreateInsertValue(RV, results[i], i);
4173 RV =
CGM.getABIInfo().createCoercedLoad(
V, RetAI, *
this);
4178 llvm_unreachable(
"Invalid ABI kind for return argument");
4181 llvm::Instruction *Ret;
4187 auto *ITy = dyn_cast<llvm::IntegerType>(RV->getType());
4194 Ret =
Builder.CreateRetVoid();
4198 Ret->setDebugLoc(std::move(RetDbgLoc));
4200 llvm::Value *Backup = RV ? Ret->getOperand(0) :
nullptr;
4201 if (RetKeyInstructionsSourceAtom)
4217 ReturnsNonNullAttr *RetNNAttr =
nullptr;
4218 if (
SanOpts.has(SanitizerKind::ReturnsNonnullAttribute))
4219 RetNNAttr =
CurCodeDecl->getAttr<ReturnsNonNullAttr>();
4221 if (!RetNNAttr && !requiresReturnValueNullabilityCheck())
4229 assert(!requiresReturnValueNullabilityCheck() &&
4230 "Cannot check nullability and the nonnull attribute");
4231 AttrLoc = RetNNAttr->getLocation();
4232 CheckKind = SanitizerKind::SO_ReturnsNonnullAttribute;
4233 Handler = SanitizerHandler::NonnullReturn;
4235 if (
auto *DD = dyn_cast<DeclaratorDecl>(
CurCodeDecl))
4236 if (
auto *TSI = DD->getTypeSourceInfo())
4238 AttrLoc = FTL.getReturnLoc().findNullabilityLoc();
4239 CheckKind = SanitizerKind::SO_NullabilityReturn;
4240 Handler = SanitizerHandler::NullabilityReturn;
4249 llvm::Value *SLocPtr =
Builder.CreateLoad(ReturnLocation,
"return.sloc.load");
4250 llvm::Value *CanNullCheck =
Builder.CreateIsNotNull(SLocPtr);
4251 if (requiresReturnValueNullabilityCheck())
4253 Builder.CreateAnd(CanNullCheck, RetValNullabilityPrecondition);
4254 Builder.CreateCondBr(CanNullCheck, Check, NoCheck);
4260 llvm::Value *DynamicData[] = {SLocPtr};
4261 EmitCheck(std::make_pair(
Cond, CheckKind), Handler, StaticData, DynamicData);
4280 llvm::Type *IRPtrTy = llvm::PointerType::getUnqual(CGF.
getLLVMContext());
4281 llvm::Value *Placeholder = llvm::PoisonValue::get(IRPtrTy);
4306 if (
type->isReferenceType()) {
4315 param->
hasAttr<NSConsumedAttr>() &&
type->isObjCRetainableType()) {
4316 llvm::Value *ptr =
Builder.CreateLoad(local);
4319 Builder.CreateStore(null, local);
4330 type->castAsRecordDecl()->isParamDestroyedInCallee() &&
4335 "cleanup for callee-destructed param not recorded");
4337 llvm::Instruction *isActive =
Builder.CreateUnreachable();
4343 return llvm::isa_and_nonnull<llvm::ConstantPointerNull>(addr);
4353 const LValue &srcLV = writeback.
Source;
4354 Address srcAddr = srcLV.getAddress();
4356 "shouldn't have writeback for provably null argument");
4364 llvm::BasicBlock *contBB =
nullptr;
4370 if (!provablyNonNull) {
4375 CGF.
Builder.CreateCondBr(isNull, contBB, writebackBB);
4384 "icr.writeback-cast");
4393 if (writeback.
ToUse) {
4418 if (!provablyNonNull)
4427 for (
const auto &I : llvm::reverse(Cleanups)) {
4429 I.IsActiveIP->eraseFromParent();
4435 if (uop->getOpcode() == UO_AddrOf)
4436 return uop->getSubExpr();
4461 Address srcAddr = srcLV.getAddress();
4466 llvm::PointerType *destType =
4468 llvm::Type *destElemType =
4495 llvm::BasicBlock *contBB =
nullptr;
4496 llvm::BasicBlock *originBB =
nullptr;
4499 llvm::Value *finalArgument;
4503 if (provablyNonNull) {
4508 finalArgument = CGF.
Builder.CreateSelect(
4509 isNull, llvm::ConstantPointerNull::get(destType),
4515 originBB = CGF.
Builder.GetInsertBlock();
4518 CGF.
Builder.CreateCondBr(isNull, contBB, copyBB);
4520 condEval.
begin(CGF);
4524 llvm::Value *valueToUse =
nullptr;
4532 src = CGF.
Builder.CreateBitCast(src, destElemType,
"icr.cast");
4549 if (shouldCopy && !provablyNonNull) {
4550 llvm::BasicBlock *copyBB = CGF.
Builder.GetInsertBlock();
4555 llvm::PHINode *phiToUse =
4556 CGF.
Builder.CreatePHI(valueToUse->getType(), 2,
"icr.to-use");
4557 phiToUse->addIncoming(valueToUse, copyBB);
4558 phiToUse->addIncoming(llvm::PoisonValue::get(valueToUse->getType()),
4560 valueToUse = phiToUse;
4574 StackBase = CGF.
Builder.CreateStackSave(
"inalloca.save");
4580 CGF.
Builder.CreateStackRestore(StackBase);
4587 if (!AC.
getDecl() || !(
SanOpts.has(SanitizerKind::NonnullAttribute) ||
4588 SanOpts.has(SanitizerKind::NullabilityArg)))
4593 unsigned ArgNo = PVD ? PVD->getFunctionScopeIndex() : ParmNum;
4596 const NonNullAttr *NNAttr =
nullptr;
4597 if (
SanOpts.has(SanitizerKind::NonnullAttribute))
4600 bool CanCheckNullability =
false;
4601 if (
SanOpts.has(SanitizerKind::NullabilityArg) && !NNAttr && PVD &&
4602 !PVD->getType()->isRecordType()) {
4603 auto Nullability = PVD->getType()->getNullability();
4604 CanCheckNullability = Nullability &&
4606 PVD->getTypeSourceInfo();
4609 if (!NNAttr && !CanCheckNullability)
4616 AttrLoc = NNAttr->getLocation();
4617 CheckKind = SanitizerKind::SO_NonnullAttribute;
4618 Handler = SanitizerHandler::NonnullArg;
4620 AttrLoc = PVD->getTypeSourceInfo()->getTypeLoc().findNullabilityLoc();
4621 CheckKind = SanitizerKind::SO_NullabilityArg;
4622 Handler = SanitizerHandler::NullabilityArg;
4627 llvm::Constant *StaticData[] = {
4630 llvm::ConstantInt::get(
Int32Ty, ArgNo + 1),
4632 EmitCheck(std::make_pair(
Cond, CheckKind), Handler, StaticData, {});
4638 if (!AC.
getDecl() || !(
SanOpts.has(SanitizerKind::NonnullAttribute) ||
4639 SanOpts.has(SanitizerKind::NullabilityArg)))
4658 return llvm::any_of(ArgTypes, [&](
QualType Ty) {
4669 return classDecl->getTypeParamListAsWritten();
4673 return catDecl->getTypeParamList();
4683 llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
4687 assert((ParamsToSkip == 0 ||
Prototype.P) &&
4688 "Can't skip parameters if type info is not provided");
4698 bool IsVariadic =
false;
4700 const auto *MD = dyn_cast<const ObjCMethodDecl *>(
Prototype.P);
4702 IsVariadic = MD->isVariadic();
4704 MD,
CGM.getTarget().getTriple().isOSWindows());
4705 ArgTypes.assign(MD->param_type_begin() + ParamsToSkip,
4706 MD->param_type_end());
4709 IsVariadic = FPT->isVariadic();
4710 ExplicitCC = FPT->getExtInfo().getCC();
4711 ArgTypes.assign(FPT->param_type_begin() + ParamsToSkip,
4712 FPT->param_type_end());
4720 assert(Arg != ArgRange.end() &&
"Running over edge of argument list!");
4727 getContext().getCanonicalType((*Arg)->getType()).getTypePtr()) &&
4728 "type mismatch in call argument!");
4734 assert((Arg == ArgRange.end() || IsVariadic) &&
4735 "Extra arguments in non-variadic function!");
4740 for (
auto *A : llvm::drop_begin(ArgRange, ArgTypes.size()))
4741 ArgTypes.push_back(IsVariadic ? getVarArgType(A) : A->getType());
4742 assert((
int)ArgTypes.size() == (ArgRange.end() - ArgRange.begin()));
4750 CGM.getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()
4754 auto MaybeEmitImplicitObjectSize = [&](
unsigned I,
const Expr *Arg,
4763 auto SizeTy = Context.getSizeType();
4765 assert(EmittedArg.getScalarVal() &&
"We emitted nothing for the arg?");
4766 llvm::Value *
V = evaluateOrEmitBuiltinObjectSize(
4767 Arg, PS->getType(),
T, EmittedArg.getScalarVal(), PS->isDynamic());
4772 std::swap(Args.back(), *(&Args.back() - 1));
4777 assert(
getTarget().getTriple().getArch() == llvm::Triple::x86 &&
4778 "inalloca only supported on x86");
4783 size_t CallArgsStart = Args.size();
4784 for (
unsigned I = 0, E = ArgTypes.size(); I != E; ++I) {
4785 unsigned Idx = LeftToRight ? I : E - I - 1;
4787 unsigned InitialArgSize = Args.size();
4791 getContext().hasSameUnqualifiedType((*Arg)->getType(),
4795 "Argument and parameter types don't match");
4799 assert(InitialArgSize + 1 == Args.size() &&
4800 "The code below depends on only adding one arg per EmitCallArg");
4801 (void)InitialArgSize;
4804 if (!Args.back().hasLValue()) {
4805 RValue RVArg = Args.back().getKnownRValue();
4807 ParamsToSkip + Idx);
4811 MaybeEmitImplicitObjectSize(Idx, *Arg, RVArg);
4818 std::reverse(Args.begin() + CallArgsStart, Args.end());
4827struct DestroyUnpassedArg final : EHScopeStack::Cleanup {
4860 if (!HasLV &&
RV.isScalar())
4862 else if (!HasLV &&
RV.isComplex())
4865 auto Addr = HasLV ?
LV.getAddress() :
RV.getAggregateAddress();
4869 HasLV ?
LV.isVolatileQualified()
4870 :
RV.isVolatileQualified());
4882 std::optional<DisableDebugLocationUpdates> Dis;
4886 dyn_cast<ObjCIndirectCopyRestoreExpr>(E)) {
4900 "reference binding to unmaterialized r-value!");
4912 if (
type->isRecordType() &&
4913 type->castAsRecordDecl()->isParamDestroyedInCallee()) {
4920 bool DestroyedInCallee =
true, NeedsCleanup =
true;
4921 if (
const auto *RD =
type->getAsCXXRecordDecl())
4922 DestroyedInCallee = RD->hasNonTrivialDestructor();
4924 NeedsCleanup =
type.isDestructedType();
4926 if (DestroyedInCallee)
4933 if (DestroyedInCallee && NeedsCleanup) {
4940 llvm::Instruction *IsActive =
4949 !
type->isArrayParameterType() && !
type.isNonTrivialToPrimitiveCopy()) {
4959QualType CodeGenFunction::getVarArgType(
const Expr *Arg) {
4963 if (!getTarget().getTriple().isOSWindows())
4967 getContext().getTypeSize(Arg->
getType()) <
4971 return getContext().getIntPtrType();
4979void CodeGenFunction::AddObjCARCExceptionMetadata(llvm::Instruction *Inst) {
4980 if (CGM.getCodeGenOpts().OptimizationLevel != 0 &&
4981 !CGM.getCodeGenOpts().ObjCAutoRefCountExceptions)
4982 Inst->setMetadata(
"clang.arc.no_objc_arc_exceptions",
4983 CGM.getNoObjCARCExceptionsMetadata());
4989 const llvm::Twine &name) {
4990 return EmitNounwindRuntimeCall(callee, ArrayRef<llvm::Value *>(), name);
4996 ArrayRef<Address> args,
4997 const llvm::Twine &name) {
4998 SmallVector<llvm::Value *, 3> values;
4999 for (
auto arg : args)
5000 values.push_back(
arg.emitRawPointer(*
this));
5001 return EmitNounwindRuntimeCall(callee, values, name);
5006 ArrayRef<llvm::Value *> args,
5007 const llvm::Twine &name) {
5008 llvm::CallInst *call = EmitRuntimeCall(callee, args, name);
5009 call->setDoesNotThrow();
5016 const llvm::Twine &name) {
5017 return EmitRuntimeCall(callee, {},
name);
5022SmallVector<llvm::OperandBundleDef, 1>
5031 if (
auto *CalleeFn = dyn_cast<llvm::Function>(Callee->stripPointerCasts())) {
5032 if (CalleeFn->isIntrinsic() && CalleeFn->doesNotThrow()) {
5033 auto IID = CalleeFn->getIntrinsicID();
5034 if (!llvm::IntrinsicInst::mayLowerToFunctionCall(IID))
5047 const llvm::Twine &name) {
5048 llvm::CallInst *call = Builder.CreateCall(
5049 callee, args, getBundlesForFunclet(callee.getCallee()), name);
5050 call->setCallingConv(getRuntimeCC());
5052 if (CGM.shouldEmitConvergenceTokens() && call->isConvergent())
5064 llvm::InvokeInst *invoke =
Builder.CreateInvoke(
5066 invoke->setDoesNotReturn();
5069 llvm::CallInst *call =
Builder.CreateCall(callee, args, BundleList);
5070 call->setDoesNotReturn();
5079 const Twine &name) {
5087 const Twine &name) {
5097 const Twine &Name) {
5102 llvm::CallBase *Inst;
5104 Inst =
Builder.CreateCall(Callee, Args, BundleList, Name);
5107 Inst =
Builder.CreateInvoke(Callee, ContBB, InvokeDest, Args, BundleList,
5114 if (
CGM.getLangOpts().ObjCAutoRefCount)
5115 AddObjCARCExceptionMetadata(Inst);
5120void CodeGenFunction::deferPlaceholderReplacement(llvm::Instruction *Old,
5122 DeferredReplacements.push_back(
5123 std::make_pair(llvm::WeakTrackingVH(Old),
New));
5130[[nodiscard]] llvm::AttributeList
5131maybeRaiseRetAlignmentAttribute(llvm::LLVMContext &Ctx,
5132 const llvm::AttributeList &Attrs,
5133 llvm::Align NewAlign) {
5134 llvm::Align CurAlign = Attrs.getRetAlignment().valueOrOne();
5135 if (CurAlign >= NewAlign)
5137 llvm::Attribute AlignAttr = llvm::Attribute::getWithAlignment(Ctx, NewAlign);
5138 return Attrs.removeRetAttribute(Ctx, llvm::Attribute::AttrKind::Alignment)
5139 .addRetAttribute(Ctx, AlignAttr);
5142template <
typename AlignedAttrTy>
class AbstractAssumeAlignedAttrEmitter {
5147 const AlignedAttrTy *AA =
nullptr;
5149 llvm::Value *Alignment =
nullptr;
5150 llvm::ConstantInt *OffsetCI =
nullptr;
5156 AA = FuncDecl->
getAttr<AlignedAttrTy>();
5161 [[nodiscard]] llvm::AttributeList
5162 TryEmitAsCallSiteAttribute(
const llvm::AttributeList &Attrs) {
5163 if (!AA || OffsetCI || CGF.
SanOpts.
has(SanitizerKind::Alignment))
5165 const auto *AlignmentCI = dyn_cast<llvm::ConstantInt>(Alignment);
5170 if (!AlignmentCI->getValue().isPowerOf2())
5172 llvm::AttributeList NewAttrs = maybeRaiseRetAlignmentAttribute(
5175 AlignmentCI->getLimitedValue(llvm::Value::MaximumAlignment)));
5183 void EmitAsAnAssumption(SourceLocation Loc, QualType RetTy, RValue &Ret) {
5187 AA->getLocation(), Alignment, OffsetCI);
5193class AssumeAlignedAttrEmitter final
5194 :
public AbstractAssumeAlignedAttrEmitter<AssumeAlignedAttr> {
5196 AssumeAlignedAttrEmitter(CodeGenFunction &CGF_,
const Decl *FuncDecl)
5197 : AbstractAssumeAlignedAttrEmitter(CGF_, FuncDecl) {
5202 if (Expr *Offset = AA->getOffset()) {
5204 if (OffsetCI->isNullValue())
5211class AllocAlignAttrEmitter final
5212 :
public AbstractAssumeAlignedAttrEmitter<AllocAlignAttr> {
5214 AllocAlignAttrEmitter(CodeGenFunction &CGF_,
const Decl *FuncDecl,
5215 const CallArgList &CallArgs)
5216 : AbstractAssumeAlignedAttrEmitter(CGF_, FuncDecl) {
5220 Alignment = CallArgs[AA->getParamIndex().getLLVMIndex()]
5229 if (
auto *VT = dyn_cast<llvm::VectorType>(Ty))
5230 return VT->getPrimitiveSizeInBits().getKnownMinValue();
5231 if (
auto *AT = dyn_cast<llvm::ArrayType>(Ty))
5234 unsigned MaxVectorWidth = 0;
5235 if (
auto *ST = dyn_cast<llvm::StructType>(Ty))
5236 for (
auto *I : ST->elements())
5238 return MaxVectorWidth;
5245 llvm::CallBase **callOrInvoke,
bool IsMustTail,
5247 bool IsVirtualFunctionPointerThunk) {
5250 assert(Callee.isOrdinary() || Callee.isVirtual());
5257 llvm::FunctionType *IRFuncTy =
getTypes().GetFunctionType(CallInfo);
5259 const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl().getDecl();
5260 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
5267 if ((TargetDecl->
hasAttr<AlwaysInlineAttr>() &&
5268 (TargetDecl->
hasAttr<TargetAttr>() ||
5272 TargetDecl->
hasAttr<TargetAttr>())))
5279 const FunctionDecl *CalleeDecl = dyn_cast_or_null<FunctionDecl>(TargetDecl);
5280 CGM.getTargetCodeGenInfo().checkFunctionCallABI(
CGM, Loc, CallerDecl,
5281 CalleeDecl, CallArgs, RetTy);
5288 if (llvm::StructType *ArgStruct = CallInfo.
getArgStruct()) {
5289 const llvm::DataLayout &DL =
CGM.getDataLayout();
5291 llvm::AllocaInst *AI;
5293 IP = IP->getNextNode();
5294 AI =
new llvm::AllocaInst(ArgStruct, DL.getAllocaAddrSpace(),
"argmem",
5300 AI->setAlignment(Align.getAsAlign());
5301 AI->setUsedWithInAlloca(
true);
5302 assert(AI->isUsedWithInAlloca() && !AI->isStaticAlloca());
5303 ArgMemory =
RawAddress(AI, ArgStruct, Align);
5306 ClangToLLVMArgMapping IRFunctionArgs(
CGM.getContext(), CallInfo);
5312 bool NeedSRetLifetimeEnd =
false;
5318 if ((IsVirtualFunctionPointerThunk || IsMustTail) && RetAI.
isIndirect()) {
5320 IRFunctionArgs.getSRetArgNo(),
5329 if (IRFunctionArgs.hasSRetArg()) {
5344 IRCallArgs[IRFunctionArgs.getSRetArgNo()] =
5362 assert(CallInfo.
arg_size() == CallArgs.size() &&
5363 "Mismatch between function signature & arguments.");
5366 for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end();
5367 I != E; ++I, ++info_it, ++ArgNo) {
5371 if (IRFunctionArgs.hasPaddingArg(ArgNo))
5372 IRCallArgs[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
5375 unsigned FirstIRArg, NumIRArgs;
5376 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
5378 bool ArgHasMaybeUndefAttr =
5383 assert(NumIRArgs == 0);
5384 assert(
getTarget().getTriple().getArch() == llvm::Triple::x86);
5385 if (I->isAggregate()) {
5387 ? I->getKnownLValue().getAddress()
5388 : I->getKnownRValue().getAggregateAddress();
5389 llvm::Instruction *Placeholder =
5394 CGBuilderTy::InsertPoint IP =
Builder.saveIP();
5395 Builder.SetInsertPoint(Placeholder);
5408 deferPlaceholderReplacement(Placeholder,
Addr.getPointer());
5413 I->Ty,
getContext().getTypeAlignInChars(I->Ty),
5414 "indirect-arg-temp");
5415 I->copyInto(*
this,
Addr);
5424 I->copyInto(*
this,
Addr);
5431 assert(NumIRArgs == 1);
5432 if (I->isAggregate()) {
5442 ? I->getKnownLValue().getAddress()
5443 : I->getKnownRValue().getAggregateAddress();
5445 const llvm::DataLayout *TD = &
CGM.getDataLayout();
5447 assert((FirstIRArg >= IRFuncTy->getNumParams() ||
5448 IRFuncTy->getParamType(FirstIRArg)->getPointerAddressSpace() ==
5449 TD->getAllocaAddrSpace()) &&
5450 "indirect argument must be in alloca address space");
5452 bool NeedCopy =
false;
5453 if (
Addr.getAlignment() < Align &&
5454 llvm::getOrEnforceKnownAlignment(
Addr.emitRawPointer(*
this),
5458 }
else if (I->hasLValue()) {
5459 auto LV = I->getKnownLValue();
5464 if (!isByValOrRef ||
5465 (LV.getAlignment() <
getContext().getTypeAlignInChars(I->Ty))) {
5469 if (isByValOrRef &&
Addr.getType()->getAddressSpace() !=
5478 auto *
T = llvm::PointerType::get(
CGM.getLLVMContext(),
5486 *
this,
V, I->Ty.getAddressSpace(),
T,
true);
5487 if (ArgHasMaybeUndefAttr)
5488 Val =
Builder.CreateFreeze(Val);
5489 IRCallArgs[FirstIRArg] = Val;
5492 }
else if (I->getType()->isArrayParameterType()) {
5498 IRCallArgs[FirstIRArg] = I->getKnownRValue().getScalarVal();
5507 if (ArgHasMaybeUndefAttr)
5508 Val =
Builder.CreateFreeze(Val);
5509 IRCallArgs[FirstIRArg] = Val;
5514 CallLifetimeEndAfterCall.emplace_back(AI);
5517 I->copyInto(*
this, AI);
5522 assert(NumIRArgs == 0);
5530 assert(NumIRArgs == 1);
5532 if (!I->isAggregate())
5533 V = I->getKnownRValue().getScalarVal();
5536 I->hasLValue() ? I->getKnownLValue().getAddress()
5537 : I->getKnownRValue().getAggregateAddress());
5543 assert(!swiftErrorTemp.
isValid() &&
"multiple swifterror args");
5547 V, pointeeTy,
getContext().getTypeAlignInChars(pointeeTy));
5554 llvm::Value *errorValue =
Builder.CreateLoad(swiftErrorArg);
5555 Builder.CreateStore(errorValue, swiftErrorTemp);
5560 V->getType()->isIntegerTy())
5567 if (FirstIRArg < IRFuncTy->getNumParams() &&
5568 V->getType() != IRFuncTy->getParamType(FirstIRArg)) {
5569 assert(
V->getType()->isPointerTy() &&
"Only pointers can mismatch!");
5570 auto ActualAS = I->Ty.getAddressSpace();
5572 *
this,
V, ActualAS, IRFuncTy->getParamType(FirstIRArg));
5575 if (ArgHasMaybeUndefAttr)
5577 IRCallArgs[FirstIRArg] =
V;
5581 llvm::StructType *STy =
5586 if (!I->isAggregate()) {
5588 I->copyInto(*
this, Src);
5590 Src = I->hasLValue() ? I->getKnownLValue().getAddress()
5591 : I->getKnownRValue().getAggregateAddress();
5601 llvm::TypeSize SrcTypeSize =
5602 CGM.getDataLayout().getTypeAllocSize(SrcTy);
5603 llvm::TypeSize DstTypeSize =
CGM.getDataLayout().getTypeAllocSize(STy);
5604 if (SrcTypeSize.isScalable()) {
5605 assert(STy->containsHomogeneousScalableVectorTypes() &&
5606 "ABI only supports structure with homogeneous scalable vector "
5608 assert(SrcTypeSize == DstTypeSize &&
5609 "Only allow non-fractional movement of structure with "
5610 "homogeneous scalable vector type");
5611 assert(NumIRArgs == STy->getNumElements());
5613 llvm::Value *StoredStructValue =
5615 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
5616 llvm::Value *Extract =
Builder.CreateExtractValue(
5617 StoredStructValue, i, Src.
getName() +
".extract" + Twine(i));
5618 IRCallArgs[FirstIRArg + i] = Extract;
5621 uint64_t SrcSize = SrcTypeSize.getFixedValue();
5622 uint64_t DstSize = DstTypeSize.getFixedValue();
5628 if (SrcSize < DstSize) {
5631 Builder.CreateMemCpy(TempAlloca, Src, SrcSize);
5637 assert(NumIRArgs == STy->getNumElements());
5638 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
5640 llvm::Value *LI =
Builder.CreateLoad(EltPtr);
5641 if (ArgHasMaybeUndefAttr)
5642 LI =
Builder.CreateFreeze(LI);
5643 IRCallArgs[FirstIRArg + i] = LI;
5648 assert(NumIRArgs == 1);
5656 auto *ATy = dyn_cast<llvm::ArrayType>(Load->getType());
5661 if (ArgHasMaybeUndefAttr)
5662 Load =
Builder.CreateFreeze(Load);
5663 IRCallArgs[FirstIRArg] = Load;
5671 auto layout =
CGM.getDataLayout().getStructLayout(coercionType);
5673 auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
5677 bool NeedLifetimeEnd =
false;
5678 if (I->isAggregate()) {
5679 addr = I->hasLValue() ? I->getKnownLValue().getAddress()
5680 : I->getKnownRValue().getAggregateAddress();
5683 RValue RV = I->getKnownRValue();
5687 auto scalarAlign =
CGM.getDataLayout().getPrefTypeAlign(scalarType);
5692 layout->getAlignment(), scalarAlign)),
5694 nullptr, &AllocaAddr);
5702 unsigned IRArgPos = FirstIRArg;
5703 unsigned unpaddedIndex = 0;
5704 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
5705 llvm::Type *eltType = coercionType->getElementType(i);
5712 : unpaddedCoercionType,
5714 if (ArgHasMaybeUndefAttr)
5715 elt =
Builder.CreateFreeze(elt);
5716 IRCallArgs[IRArgPos++] = elt;
5718 assert(IRArgPos == FirstIRArg + NumIRArgs);
5720 if (NeedLifetimeEnd)
5726 unsigned IRArgPos = FirstIRArg;
5727 ExpandTypeToArgs(I->Ty, *I, IRFuncTy, IRCallArgs, IRArgPos);
5728 assert(IRArgPos == FirstIRArg + NumIRArgs);
5734 if (!I->isAggregate()) {
5736 I->copyInto(*
this, Src);
5738 Src = I->hasLValue() ? I->getKnownLValue().getAddress()
5739 : I->getKnownRValue().getAggregateAddress();
5745 CGM.getABIInfo().createCoercedLoad(Src, ArgInfo, *
this);
5746 IRCallArgs[FirstIRArg] = Load;
5752 const CGCallee &ConcreteCallee = Callee.prepareConcreteCallee(*
this);
5758 assert(IRFunctionArgs.hasInallocaArg());
5759 IRCallArgs[IRFunctionArgs.getInallocaArgNo()] = Arg;
5770 auto simplifyVariadicCallee = [](llvm::FunctionType *CalleeFT,
5771 llvm::Value *Ptr) -> llvm::Function * {
5772 if (!CalleeFT->isVarArg())
5776 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Ptr)) {
5777 if (CE->getOpcode() == llvm::Instruction::BitCast)
5778 Ptr = CE->getOperand(0);
5781 llvm::Function *OrigFn = dyn_cast<llvm::Function>(Ptr);
5785 llvm::FunctionType *OrigFT = OrigFn->getFunctionType();
5789 if (OrigFT->isVarArg() ||
5790 OrigFT->getNumParams() != CalleeFT->getNumParams() ||
5791 OrigFT->getReturnType() != CalleeFT->getReturnType())
5794 for (
unsigned i = 0, e = OrigFT->getNumParams(); i != e; ++i)
5795 if (OrigFT->getParamType(i) != CalleeFT->getParamType(i))
5801 if (llvm::Function *OrigFn = simplifyVariadicCallee(IRFuncTy, CalleePtr)) {
5803 IRFuncTy = OrigFn->getFunctionType();
5814 for (
unsigned i = 0; i < IRCallArgs.size(); ++i)
5815 LargestVectorWidth = std::max(LargestVectorWidth,
5820 llvm::AttributeList Attrs;
5821 CGM.ConstructAttributeList(CalleePtr->getName(), CallInfo,
5826 if (
CallingConv == llvm::CallingConv::X86_VectorCall &&
5827 getTarget().getTriple().isWindowsArm64EC()) {
5828 CGM.Error(Loc,
"__vectorcall calling convention is not currently "
5833 if (FD->hasAttr<StrictFPAttr>())
5835 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::StrictFP);
5840 if (FD->hasAttr<OptimizeNoneAttr>() &&
getLangOpts().FastMath)
5841 CGM.AdjustMemoryAttribute(CalleePtr->getName(), Callee.getAbstractInfo(),
5846 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::NoMerge);
5850 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::NoInline);
5855 !
CGM.getTargetCodeGenInfo().wouldInliningViolateFunctionCallABI(
5856 CallerDecl, CalleeDecl))
5858 Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::AlwaysInline);
5863 Attrs.removeFnAttribute(
getLLVMContext(), llvm::Attribute::Convergent);
5872 !(TargetDecl && TargetDecl->
hasAttr<NoInlineAttr>()) &&
5873 !
CGM.getTargetCodeGenInfo().wouldInliningViolateFunctionCallABI(
5874 CallerDecl, CalleeDecl)) {
5876 Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::AlwaysInline);
5881 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::NoInline);
5888 CannotThrow =
false;
5897 CannotThrow = Attrs.hasFnAttr(llvm::Attribute::NoUnwind);
5899 if (
auto *FPtr = dyn_cast<llvm::Function>(CalleePtr))
5900 if (FPtr->hasFnAttribute(llvm::Attribute::NoUnwind))
5908 if (NeedSRetLifetimeEnd)
5916 if (
SanOpts.has(SanitizerKind::KCFI) &&
5917 !isa_and_nonnull<FunctionDecl>(TargetDecl))
5924 if (FD->hasAttr<StrictFPAttr>())
5926 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::StrictFP);
5928 AssumeAlignedAttrEmitter AssumeAlignedAttrEmitter(*
this, TargetDecl);
5929 Attrs = AssumeAlignedAttrEmitter.TryEmitAsCallSiteAttribute(Attrs);
5931 AllocAlignAttrEmitter AllocAlignAttrEmitter(*
this, TargetDecl, CallArgs);
5932 Attrs = AllocAlignAttrEmitter.TryEmitAsCallSiteAttribute(Attrs);
5937 CI =
Builder.CreateCall(IRFuncTy, CalleePtr, IRCallArgs, BundleList);
5940 CI =
Builder.CreateInvoke(IRFuncTy, CalleePtr, Cont, InvokeDest, IRCallArgs,
5944 if (CI->getCalledFunction() && CI->getCalledFunction()->hasName() &&
5945 CI->getCalledFunction()->getName().starts_with(
"_Z4sqrt")) {
5954 if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(
CurFuncDecl)) {
5955 if (
const auto *A = FD->getAttr<CFGuardAttr>()) {
5956 if (A->getGuard() == CFGuardAttr::GuardArg::nocf &&
5957 !CI->getCalledFunction())
5963 CI->setAttributes(Attrs);
5964 CI->setCallingConv(
static_cast<llvm::CallingConv::ID
>(
CallingConv));
5968 if (!CI->getType()->isVoidTy())
5969 CI->setName(
"call");
5971 if (
CGM.shouldEmitConvergenceTokens() && CI->isConvergent())
5972 CI = addConvergenceControlToken(CI);
5975 LargestVectorWidth =
5981 if (!CI->getCalledFunction())
5982 PGO->valueProfile(
Builder, llvm::IPVK_IndirectCallTarget, CI, CalleePtr);
5986 if (
CGM.getLangOpts().ObjCAutoRefCount)
5987 AddObjCARCExceptionMetadata(CI);
5990 if (llvm::CallInst *
Call = dyn_cast<llvm::CallInst>(CI)) {
5991 if (TargetDecl && TargetDecl->
hasAttr<NotTailCalledAttr>())
5992 Call->setTailCallKind(llvm::CallInst::TCK_NoTail);
5993 else if (IsMustTail) {
5996 CGM.getDiags().Report(Loc, diag::err_aix_musttail_unsupported);
5999 CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail) << 0;
6000 else if (
Call->isIndirectCall())
6001 CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail) << 1;
6002 else if (isa_and_nonnull<FunctionDecl>(TargetDecl)) {
6007 CGM.addUndefinedGlobalForTailCall(
6010 llvm::GlobalValue::LinkageTypes
Linkage =
CGM.getFunctionLinkage(
6012 if (llvm::GlobalValue::isWeakForLinker(
Linkage) ||
6013 llvm::GlobalValue::isDiscardableIfUnused(
Linkage))
6014 CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail)
6020 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
6029 if (TargetDecl && TargetDecl->
hasAttr<ErrorAttr>()) {
6030 llvm::ConstantInt *
Line =
6032 llvm::ConstantAsMetadata *MD = llvm::ConstantAsMetadata::get(
Line);
6034 CI->setMetadata(
"srcloc", MDT);
6042 if (CI->doesNotReturn()) {
6043 if (NeedSRetLifetimeEnd)
6047 if (
SanOpts.has(SanitizerKind::Unreachable)) {
6050 if (
auto *F = CI->getCalledFunction())
6051 F->removeFnAttr(llvm::Attribute::NoReturn);
6052 CI->removeFnAttr(llvm::Attribute::NoReturn);
6056 if (
SanOpts.hasOneOf(SanitizerKind::Address |
6057 SanitizerKind::KernelAddress)) {
6059 llvm::IRBuilder<>::InsertPointGuard IPGuard(
Builder);
6061 auto *FnType = llvm::FunctionType::get(
CGM.VoidTy,
false);
6062 llvm::FunctionCallee Fn =
6063 CGM.CreateRuntimeFunction(FnType,
"__asan_handle_no_return");
6069 Builder.ClearInsertionPoint();
6088 if (Cleanup && Cleanup->isFakeUse()) {
6089 CGBuilderTy::InsertPointGuard IPG(
Builder);
6091 Cleanup->getCleanup()->Emit(*
this, EHScopeStack::Cleanup::Flags());
6092 }
else if (!(Cleanup &&
6093 Cleanup->getCleanup()->isRedundantBeforeReturn())) {
6094 CGM.ErrorUnsupported(
MustTailCall,
"tail call skipping over cleanups");
6097 if (CI->getType()->isVoidTy())
6101 Builder.ClearInsertionPoint();
6107 if (swiftErrorTemp.
isValid()) {
6108 llvm::Value *errorResult =
Builder.CreateLoad(swiftErrorTemp);
6109 Builder.CreateStore(errorResult, swiftErrorArg);
6126 if (IsVirtualFunctionPointerThunk) {
6139 unsigned unpaddedIndex = 0;
6140 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
6141 llvm::Type *eltType = coercionType->getElementType(i);
6145 llvm::Value *elt = CI;
6146 if (requiresExtract)
6147 elt =
Builder.CreateExtractValue(elt, unpaddedIndex++);
6149 assert(unpaddedIndex == 0);
6150 Builder.CreateStore(elt, eltAddr);
6158 if (NeedSRetLifetimeEnd)
6175 llvm::Value *Real =
Builder.CreateExtractValue(CI, 0);
6176 llvm::Value *Imag =
Builder.CreateExtractValue(CI, 1);
6184 llvm::Value *
V = CI;
6185 if (
V->getType() != RetIRTy)
6195 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(RetIRTy)) {
6196 llvm::Value *
V = CI;
6197 if (
auto *ScalableSrcTy =
6198 dyn_cast<llvm::ScalableVectorType>(
V->getType())) {
6199 if (FixedDstTy->getElementType() ==
6200 ScalableSrcTy->getElementType()) {
6201 V =
Builder.CreateExtractVector(FixedDstTy,
V, uint64_t(0),
6211 getContext().getTypeInfoDataSizeInChars(RetTy).Width.getQuantity();
6215 DestIsVolatile =
false;
6216 DestSize =
getContext().getTypeSizeInChars(RetTy).getQuantity();
6240 DestIsVolatile =
false;
6242 CGM.getABIInfo().createCoercedStore(CI, StorePtr, RetAI, DestIsVolatile,
6249 llvm_unreachable(
"Invalid ABI kind for return argument");
6252 llvm_unreachable(
"Unhandled ABIArgInfo::Kind");
6257 if (Ret.isScalar() && TargetDecl) {
6258 AssumeAlignedAttrEmitter.EmitAsAnAssumption(Loc, RetTy, Ret);
6259 AllocAlignAttrEmitter.EmitAsAnAssumption(Loc, RetTy, Ret);
6265 LifetimeEnd.Emit(*
this, {});
6295 if (
VE->isMicrosoftABI())
6296 return CGM.getABIInfo().EmitMSVAArg(*
this, VAListAddr, Ty, Slot);
6297 return CGM.getABIInfo().EmitVAArg(*
this, VAListAddr, Ty, Slot);
6302 CGF.disableDebugInfo();
6306 CGF.enableDebugInfo();
static ExtParameterInfoList getExtParameterInfosForCall(const FunctionProtoType *proto, unsigned prefixArgs, unsigned totalArgs)
static bool isInAllocaArgument(CGCXXABI &ABI, QualType type)
static uint64_t buildMultiCharMask(const SmallVectorImpl< uint64_t > &Bits, int Pos, int Size, int CharWidth, bool BigEndian)
static llvm::Value * tryRemoveRetainOfSelf(CodeGenFunction &CGF, llvm::Value *result)
If this is a +1 of the value of an immutable 'self', remove it.
static CanQualType GetReturnType(QualType RetTy)
Returns the "extra-canonicalized" return type, which discards qualifiers on the return type.
static const NonNullAttr * getNonNullAttr(const Decl *FD, const ParmVarDecl *PVD, QualType ArgType, unsigned ArgNo)
Returns the attribute (either parameter attribute, or function attribute), which declares argument Ar...
static CanQualTypeList getArgTypesForCall(ASTContext &ctx, const CallArgList &args)
static Address emitAddressAtOffset(CodeGenFunction &CGF, Address addr, const ABIArgInfo &info)
static AggValueSlot createPlaceholderSlot(CodeGenFunction &CGF, QualType Ty)
static CallingConv getCallingConventionForDecl(const ObjCMethodDecl *D, bool IsTargetDefaultMSABI)
static void setBitRange(SmallVectorImpl< uint64_t > &Bits, int BitOffset, int BitWidth, int CharWidth)
static bool isProvablyNull(llvm::Value *addr)
static void AddAttributesFromFunctionProtoType(ASTContext &Ctx, llvm::AttrBuilder &FuncAttrs, const FunctionProtoType *FPT)
static void eraseUnusedBitCasts(llvm::Instruction *insn)
static bool isObjCMethodWithTypeParams(const ObjCMethodDecl *method)
static void addNoBuiltinAttributes(llvm::AttrBuilder &FuncAttrs, const LangOptions &LangOpts, const NoBuiltinAttr *NBA=nullptr)
static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args, const ObjCIndirectCopyRestoreExpr *CRE)
Emit an argument that's being passed call-by-writeback.
static void overrideFunctionFeaturesWithTargetFeatures(llvm::AttrBuilder &FuncAttr, const llvm::Function &F, const TargetOptions &TargetOpts)
Merges target-features from \TargetOpts and \F, and sets the result in \FuncAttr.
static llvm::Value * CreateCoercedLoad(Address Src, llvm::Type *Ty, CodeGenFunction &CGF)
CreateCoercedLoad - Create a load from.
static int getExpansionSize(QualType Ty, const ASTContext &Context)
static CanQual< FunctionProtoType > GetFormalType(const CXXMethodDecl *MD)
Returns the canonical formal type of the given C++ method.
static bool DetermineNoUndef(QualType QTy, CodeGenTypes &Types, const llvm::DataLayout &DL, const ABIArgInfo &AI, bool CheckCoerce=true)
static const Expr * maybeGetUnaryAddrOfOperand(const Expr *E)
static void addDenormalModeAttrs(llvm::DenormalMode FPDenormalMode, llvm::DenormalMode FP32DenormalMode, llvm::AttrBuilder &FuncAttrs)
Add denormal-fp-math and denormal-fp-math-f32 as appropriate for the requested denormal behavior,...
static void deactivateArgCleanupsBeforeCall(CodeGenFunction &CGF, const CallArgList &CallArgs)
static bool isProvablyNonNull(Address Addr, CodeGenFunction &CGF)
static llvm::Value * emitArgumentDemotion(CodeGenFunction &CGF, const VarDecl *var, llvm::Value *value)
An argument came in as a promoted argument; demote it back to its declared type.
SmallVector< CanQualType, 16 > CanQualTypeList
static std::pair< llvm::Value *, bool > CoerceScalableToFixed(CodeGenFunction &CGF, llvm::FixedVectorType *ToTy, llvm::ScalableVectorType *FromTy, llvm::Value *V, StringRef Name="")
static const CGFunctionInfo & arrangeLLVMFunctionInfo(CodeGenTypes &CGT, bool instanceMethod, SmallVectorImpl< CanQualType > &prefix, CanQual< FunctionProtoType > FTP)
Arrange the LLVM function layout for a value of the given function type, on top of any implicit param...
static void addExtParameterInfosForCall(llvm::SmallVectorImpl< FunctionProtoType::ExtParameterInfo > ¶mInfos, const FunctionProtoType *proto, unsigned prefixArgs, unsigned totalArgs)
static bool canApplyNoFPClass(const ABIArgInfo &AI, QualType ParamType, bool IsReturn)
Test if it's legal to apply nofpclass for the given parameter type and it's lowered IR type.
static void getTrivialDefaultFunctionAttributes(StringRef Name, bool HasOptnone, const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts, bool AttrOnCallSite, llvm::AttrBuilder &FuncAttrs)
static llvm::FPClassTest getNoFPClassTestMask(const LangOptions &LangOpts)
Return the nofpclass mask that can be applied to floating-point parameters.
static void forConstantArrayExpansion(CodeGenFunction &CGF, ConstantArrayExpansion *CAE, Address BaseAddr, llvm::function_ref< void(Address)> Fn)
static bool IsArgumentMaybeUndef(const Decl *TargetDecl, unsigned NumRequiredArgs, unsigned ArgNo)
Check if the argument of a function has maybe_undef attribute.
static bool hasInAllocaArgs(CodeGenModule &CGM, CallingConv ExplicitCC, ArrayRef< QualType > ArgTypes)
static std::unique_ptr< TypeExpansion > getTypeExpansion(QualType Ty, const ASTContext &Context)
SmallVector< FunctionProtoType::ExtParameterInfo, 16 > ExtParameterInfoList
static RawAddress CreateTempAllocaForCoercion(CodeGenFunction &CGF, llvm::Type *Ty, CharUnits MinAlign, const Twine &Name="tmp")
Create a temporary allocation for the purposes of coercion.
static void setUsedBits(CodeGenModule &, QualType, int, SmallVectorImpl< uint64_t > &)
static llvm::StoreInst * findDominatingStoreToReturnValue(CodeGenFunction &CGF)
Heuristically search for a dominating store to the return-value slot.
static void setCUDAKernelCallingConvention(CanQualType &FTy, CodeGenModule &CGM, const FunctionDecl *FD)
Set calling convention for CUDA/HIP kernel.
static llvm::Value * tryEmitFusedAutoreleaseOfResult(CodeGenFunction &CGF, llvm::Value *result)
Try to emit a fused autorelease of a return result.
static Address EnterStructPointerForCoercedAccess(Address SrcPtr, llvm::StructType *SrcSTy, uint64_t DstSize, CodeGenFunction &CGF)
EnterStructPointerForCoercedAccess - Given a struct pointer that we are accessing some number of byte...
static llvm::Value * emitAutoreleaseOfResult(CodeGenFunction &CGF, llvm::Value *result)
Emit an ARC autorelease of the result of a function.
static void emitWriteback(CodeGenFunction &CGF, const CallArgList::Writeback &writeback)
Emit the actual writing-back of a writeback.
static bool HasStrictReturn(const CodeGenModule &Module, QualType RetTy, const Decl *TargetDecl)
static CanQualTypeList getArgTypesForDeclaration(ASTContext &ctx, const FunctionArgList &args)
static void addMergableDefaultFunctionAttributes(const CodeGenOptions &CodeGenOpts, llvm::AttrBuilder &FuncAttrs)
Add default attributes to a function, which have merge semantics under -mlink-builtin-bitcode and sho...
static llvm::Value * CoerceIntOrPtrToIntOrPtr(llvm::Value *Val, llvm::Type *Ty, CodeGenFunction &CGF)
CoerceIntOrPtrToIntOrPtr - Convert a value Val to the specific Ty where both are either integers or p...
static void AddAttributesFromOMPAssumes(llvm::AttrBuilder &FuncAttrs, const Decl *Callee)
static unsigned getMaxVectorWidth(const llvm::Type *Ty)
CodeGenFunction::ComplexPairTy ComplexPairTy
static void appendParameterTypes(const CIRGenTypes &cgt, SmallVectorImpl< CanQualType > &prefix, CanQual< FunctionProtoType > fpt)
Adds the formal parameters in FPT to the given prefix.
static const CIRGenFunctionInfo & arrangeFreeFunctionLikeCall(CIRGenTypes &cgt, CIRGenModule &cgm, const CallArgList &args, const FunctionType *fnType)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
#define CC_VLS_CASE(ABI_VLEN)
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 QualType getPointeeType(const MemRegion *R)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CanQualType getCanonicalParamType(QualType T) const
Return the canonical parameter type corresponding to the specific potentially non-canonical one.
CanQualType getCanonicalSizeType() const
const TargetInfo & getTargetInfo() const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Attr - This represents one attribute.
This class is used for builtin types like 'int'.
QualType getType() const
Retrieves the type of the base class.
Represents a C++ constructor within a class.
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Qualifiers getMethodQualifiers() const
Represents a C++ struct/union/class.
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
SourceLocation getBeginLoc() const
ConstExprIterator const_arg_iterator
Represents a canonical, potentially-qualified type.
static CanQual< Type > CreateUnsafe(QualType Other)
CanProxy< U > castAs() const
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
CanProxy< U > getAs() const
Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
llvm::DenormalMode FPDenormalMode
The floating-point denormal mode to use.
static StringRef getFramePointerKindName(FramePointerKind Kind)
std::vector< std::string > Reciprocals
llvm::DenormalMode FP32DenormalMode
The floating-point denormal mode to use, for float.
std::string TrapFuncName
If not an empty string, trap intrinsics are lowered to calls to this function instead of to trap inst...
std::vector< std::string > DefaultFunctionAttrs
std::string PreferVectorWidth
The preferred width for auto-vectorization transforms.
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
unsigned getInAllocaFieldIndex() const
bool getIndirectByVal() const
llvm::StructType * getCoerceAndExpandType() const
bool getIndirectRealign() const
void setCoerceToType(llvm::Type *T)
llvm::Type * getUnpaddedCoerceAndExpandType() const
bool getCanBeFlattened() const
unsigned getDirectOffset() const
static bool isPaddingForCoerceAndExpand(llvm::Type *eltType)
bool getInAllocaSRet() const
Return true if this field of an inalloca struct should be returned to implement a struct return calli...
llvm::Type * getPaddingType() const
bool getPaddingInReg() const
unsigned getDirectAlign() const
unsigned getIndirectAddrSpace() const
@ Extend
Extend - Valid only for integer argument types.
@ Ignore
Ignore - Ignore the argument (treat as void).
@ IndirectAliased
IndirectAliased - Similar to Indirect, but the pointer may be to an object that is otherwise referenc...
@ Expand
Expand - Only valid for aggregate argument types.
@ TargetSpecific
TargetSpecific - Some argument types are passed as target specific types such as RISC-V's tuple type,...
@ InAlloca
InAlloca - Pass the argument directly using the LLVM inalloca attribute.
@ Indirect
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
@ CoerceAndExpand
CoerceAndExpand - Only valid for aggregate argument types.
@ Direct
Direct - Pass the argument directly using the normal converted LLVM type, or by coercing to another s...
ArrayRef< llvm::Type * > getCoerceAndExpandTypeSequence() const
bool isCoerceAndExpand() const
unsigned getInAllocaIndirect() const
llvm::Type * getCoerceToType() const
bool isIndirectAliased() const
bool isSRetAfterThis() const
bool canHaveCoerceToType() const
CharUnits getIndirectAlign() const
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * getBasePointer() const
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withPointer(llvm::Value *NewPointer, KnownNonNull_t IsKnownNonNull) const
Return address with different pointer, but same element type and alignment.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
unsigned getAddressSpace() const
Return the address space that this address resides in.
KnownNonNull_t isKnownNonNull() const
Whether the pointer is known not to be null.
llvm::StringRef getName() const
Return the IR name of the pointer value.
Address getAddress() const
void setExternallyDestructed(bool destructed=true)
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
forAddr - Make a slot for an aggregate value.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
Address CreateConstGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, const llvm::Twine &Name="")
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
Implements C++ ABI-specific code generation functions.
virtual bool hasMostDerivedReturn(GlobalDecl GD) const
virtual bool HasThisReturn(GlobalDecl GD) const
Returns true if the given constructor or destructor is one of the kinds that the ABI says returns 'th...
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
virtual CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD, Address This, llvm::Type *Ty, SourceLocation Loc)=0
Build a virtual function pointer in the ABI-specific way.
virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const =0
Returns how an argument of the given record type should be passed.
virtual const CXXRecordDecl * getThisArgumentTypeForMethod(GlobalDecl GD)
Get the type of the implicit "this" parameter used by a method.
virtual AddedStructorArgCounts buildStructorSignature(GlobalDecl GD, SmallVectorImpl< CanQualType > &ArgTys)=0
Build the signature of the given constructor or destructor variant by adding any required parameters.
Abstract information about a function or function prototype.
const GlobalDecl getCalleeDecl() const
const FunctionProtoType * getCalleeFunctionProtoType() const
All available information about a concrete callee.
CGCallee prepareConcreteCallee(CodeGenFunction &CGF) const
If this is a delayed callee computation of some sort, prepare a concrete callee.
Address getThisAddress() const
const CallExpr * getVirtualCallExpr() const
llvm::Value * getFunctionPointer() const
llvm::FunctionType * getVirtualFunctionType() const
const CGPointerAuthInfo & getPointerAuthInfo() const
GlobalDecl getVirtualMethodDecl() const
CGFunctionInfo - Class to encapsulate the information about a function definition.
bool usesInAlloca() const
Return true if this function uses inalloca arguments.
FunctionType::ExtInfo getExtInfo() const
bool isInstanceMethod() const
ABIArgInfo & getReturnInfo()
bool isReturnsRetained() const
In ARC, whether this function retains its return value.
void Profile(llvm::FoldingSetNodeID &ID)
const_arg_iterator arg_begin() const
ArrayRef< ExtParameterInfo > getExtParameterInfos() const
CanQualType getReturnType() const
const ArgInfo * const_arg_iterator
static CGFunctionInfo * create(unsigned llvmCC, bool instanceMethod, bool chainCall, bool delegateCall, const FunctionType::ExtInfo &extInfo, ArrayRef< ExtParameterInfo > paramInfos, CanQualType resultType, ArrayRef< CanQualType > argTypes, RequiredArgs required)
bool isCmseNSCall() const
bool isDelegateCall() const
MutableArrayRef< ArgInfo > arguments()
const_arg_iterator arg_end() const
unsigned getEffectiveCallingConvention() const
getEffectiveCallingConvention - Return the actual calling convention to use, which may depend on the ...
ExtParameterInfo getExtParameterInfo(unsigned argIndex) const
CharUnits getArgStructAlignment() const
unsigned arg_size() const
RequiredArgs getRequiredArgs() const
unsigned getNumRequiredArgs() const
llvm::StructType * getArgStruct() const
Get the struct type used to represent all the arguments in memory.
CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
CallArgList - Type for representing both the value and type of arguments in a call.
void addWriteback(LValue srcLV, Address temporary, llvm::Value *toUse, const Expr *writebackExpr=nullptr)
llvm::Instruction * getStackBase() const
void addUncopiedAggregate(LValue LV, QualType type)
void addArgCleanupDeactivation(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *IsActiveIP)
ArrayRef< CallArgCleanup > getCleanupsToDeactivate() const
bool hasWritebacks() const
void add(RValue rvalue, QualType type)
bool isUsingInAlloca() const
Returns if we're using an inalloca struct to pass arguments in memory.
void allocateArgumentMemory(CodeGenFunction &CGF)
void freeArgumentMemory(CodeGenFunction &CGF) const
writeback_const_range writebacks() const
An abstract representation of regular/ObjC call/message targets.
const ParmVarDecl * getParamDecl(unsigned I) const
const Decl * getDecl() const
unsigned getNumParams() const
bool hasFunctionDecl() const
An object to manage conditionally-evaluated expressions.
void begin(CodeGenFunction &CGF)
void end(CodeGenFunction &CGF)
static ParamValue forIndirect(Address addr)
static ParamValue forDirect(llvm::Value *value)
RAII object to set/unset CodeGenFunction::IsSanitizerScope.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void CreateCoercedStore(llvm::Value *Src, Address Dst, llvm::TypeSize DstSize, bool DstIsVolatile)
Create a store to.
EHScopeStack::stable_iterator CurrentCleanupScopeDepth
llvm::Value * EmitARCRetainAutoreleaseReturnValue(llvm::Value *value)
Do a fused retain/autorelease of the given object.
SanitizerSet SanOpts
Sanitizers enabled for this function.
void checkTargetFeatures(const CallExpr *E, const FunctionDecl *TargetDecl)
static bool hasScalarEvaluationKind(QualType T)
llvm::Type * ConvertType(QualType T)
bool isCleanupPadScope() const
Returns true while emitting a cleanuppad.
void addInstToNewSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
Add KeyInstruction and an optional Backup instruction to a new atom group (See ApplyAtomGroup for mor...
llvm::CallBase * EmitCallOrInvoke(llvm::FunctionCallee Callee, ArrayRef< llvm::Value * > Args, const Twine &Name="")
Emits a call or invoke instruction to the given function, depending on the current state of the EH st...
void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args)
Emits a call or invoke to the given noreturn runtime function.
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
void callCStructDestructor(LValue Dst)
ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)
EmitLoadOfComplex - Load a complex number from the specified l-value.
llvm::Value * EmitARCAutoreleaseReturnValue(llvm::Value *value)
Autorelease the given object.
bool shouldUseFusedARCCalls()
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
bool isSEHTryScope() const
Returns true inside SEH __try blocks.
RValue convertTempToRValue(Address addr, QualType type, SourceLocation Loc)
Given the address of a temporary variable, produce an r-value of its type.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
void SetSqrtFPAccuracy(llvm::Value *Val)
Set the minimum required accuracy of the given sqrt operation based on CodeGenOpts.
RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr, AggValueSlot Slot=AggValueSlot::ignored())
Generate code to get an argument from the passed in pointer and update it accordingly.
void EmitReturnValueCheck(llvm::Value *RV)
Emit a test that checks if the return value RV is nonnull.
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
void EmitDelegateCallArg(CallArgList &args, const VarDecl *param, SourceLocation loc)
EmitDelegateCallArg - We are performing a delegate call; that is, the current function is delegating ...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
See CGDebugInfo::addInstToCurrentSourceAtom.
const LangOptions & getLangOpts() const
void addInstToSpecificSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup, uint64_t Atom)
See CGDebugInfo::addInstToSpecificSourceAtom.
RValue EmitReferenceBindingToExpr(const Expr *E)
Emits a reference binding to the passed in expression.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
bool InNoConvergentAttributedStmt
True if the current statement has noconvergent attribute.
void pushDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
pushDestroy - Push the standard destructor for the given type as at least a normal cleanup.
const CodeGen::CGBlockInfo * BlockInfo
void EmitKCFIOperandBundle(const CGCallee &Callee, SmallVectorImpl< llvm::OperandBundleDef > &Bundles)
Address makeNaturalAddressForPointer(llvm::Value *Ptr, QualType T, CharUnits Alignment=CharUnits::Zero(), bool ForPointeeType=false, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
Construct an address with the natural alignment of T.
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
bool InNoMergeAttributedStmt
True if the current statement has nomerge attribute.
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
llvm::BasicBlock * getUnreachableBlock()
void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)
Release the given object.
bool currentFunctionUsesSEHTry() const
JumpDest ReturnBlock
ReturnBlock - Unified return block.
@ ForceLeftToRight
! Language semantics require left-to-right evaluation.
@ ForceRightToLeft
! Language semantics require right-to-left evaluation.
void EmitNonNullArgCheck(RValue RV, QualType ArgType, SourceLocation ArgLoc, AbstractCallee AC, unsigned ParmNum)
Create a check for a function parameter that may potentially be declared as non-null.
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
const TargetInfo & getTarget() const
LValue EmitHLSLOutArgExpr(const HLSLOutArgExpr *E, CallArgList &Args, QualType Ty)
void EmitWritebacks(const CallArgList &Args)
EmitWriteback - Emit callbacks for function.
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
DeactivateCleanupBlock - Deactivates the given cleanup block.
void pushFullExprCleanup(CleanupKind kind, As... A)
pushFullExprCleanup - Push a cleanup to be run at the end of the current full-expression.
llvm::BasicBlock * getInvokeDest()
void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType)
EmitCallArg - Emit a single call argument.
void EmitPointerAuthOperandBundle(const CGPointerAuthInfo &Info, SmallVectorImpl< llvm::OperandBundleDef > &Bundles)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
AggValueSlot CreateAggTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateAggTemp - Create a temporary memory object for the given aggregate type.
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
CGDebugInfo * getDebugInfo()
bool EmitLifetimeStart(llvm::Value *Addr)
Emit a lifetime.begin marker if some criteria are satisfied.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
const TargetCodeGenInfo & getTargetHooks() const
void EmitLifetimeEnd(llvm::Value *Addr)
RawAddress CreateMemTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen without...
bool InNoInlineAttributedStmt
True if the current statement has noinline attribute.
SmallVector< llvm::OperandBundleDef, 1 > getBundlesForFunclet(llvm::Value *Callee)
RValue EmitAnyExprToTemp(const Expr *E)
EmitAnyExprToTemp - Similarly to EmitAnyExpr(), however, the result will always be accessible even if...
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void EmitFunctionProlog(const CGFunctionInfo &FI, llvm::Function *Fn, const FunctionArgList &Args)
EmitFunctionProlog - Emit the target specific LLVM code to load the arguments for the given function.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
Address EmitVAListRef(const Expr *E)
RValue GetUndefRValue(QualType Ty)
GetUndefRValue - Get an appropriate 'undef' rvalue for the given type.
void EmitParmDecl(const VarDecl &D, ParamValue Arg, unsigned ArgNo)
EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl.
bool AutoreleaseResult
In ARC, whether we should autorelease the return value.
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)
Retain the given object, with normal retain semantics.
llvm::Type * ConvertTypeForMem(QualType T)
CodeGenTypes & getTypes() const
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
bool InAlwaysInlineAttributedStmt
True if the current statement has always_inline attribute.
void EmitFunctionEpilog(const CGFunctionInfo &FI, bool EmitRetDbgLoc, SourceLocation EndLoc, uint64_t RetKeyInstructionsSourceAtom)
EmitFunctionEpilog - Emit the target specific LLVM code to return the given temporary.
Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
Address EmitMSVAListRef(const Expr *E)
Emit a "reference" to a __builtin_ms_va_list; this is always the value of the expression,...
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
static bool hasAggregateEvaluationKind(QualType T)
void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)
EmitCallArgs - Emit call arguments for a function.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
const CallExpr * MustTailCall
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
void EmitUnreachable(SourceLocation Loc)
Emit a reached-unreachable diagnostic if Loc is valid and runtime checking is enabled.
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
llvm::Instruction * CurrentFuncletPad
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
llvm::LLVMContext & getLLVMContext()
void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
llvm::Value * EmitNonNullRValueCheck(RValue RV, QualType T)
Create a check that a scalar RValue is non-null.
void EmitARCIntrinsicUse(ArrayRef< llvm::Value * > values)
Given a number of pointers, inform the optimizer that they're being intrinsically used up until this ...
llvm::Value * EmitCMSEClearRecord(llvm::Value *V, llvm::IntegerType *ITy, QualType RTy)
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
bool ReturnTypeUsesFPRet(QualType ResultType)
Return true iff the given type uses 'fpret' when used as a return type.
const LangOptions & getLangOpts() const
CharUnits getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, bool forPointeeType=false)
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
const llvm::DataLayout & getDataLayout() const
ObjCEntrypoints & getObjCEntrypoints() const
CGCXXABI & getCXXABI() const
bool ReturnTypeUsesFP2Ret(QualType ResultType)
Return true iff the given type uses 'fp2ret' when used as a return type.
bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI)
Return true iff the given type uses an argument slot when 'sret' is used as a return type.
bool ReturnTypeHasInReg(const CGFunctionInfo &FI)
Return true iff the given type has inreg set.
void AdjustMemoryAttribute(StringRef Name, CGCalleeInfo CalleeInfo, llvm::AttributeList &Attrs)
Adjust Memory attribute to ensure that the BE gets the right attribute.
void ConstructAttributeList(StringRef Name, const CGFunctionInfo &Info, CGCalleeInfo CalleeInfo, llvm::AttributeList &Attrs, unsigned &CallingConv, bool AttrOnCallSite, bool IsThunk)
Get the LLVM attributes and calling convention to use for a particular function type.
ASTContext & getContext() const
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)
Return true iff the given type uses 'sret' when used as a return type.
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
void addDefaultFunctionDefinitionAttributes(llvm::AttrBuilder &attrs)
Like the overload taking a Function &, but intended specifically for frontends that want to build on ...
CharUnits getNaturalPointeeTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
llvm::LLVMContext & getLLVMContext()
CharUnits getMinimumObjectSize(QualType Ty)
Returns the minimum object size for an object of the given type.
bool MayDropFunctionReturn(const ASTContext &Context, QualType ReturnType) const
Whether this function's return type has no side effects, and thus may be trivially discarded if it is...
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
const CGFunctionInfo & arrangeCXXMethodType(const CXXRecordDecl *RD, const FunctionProtoType *FTP, const CXXMethodDecl *MD)
Arrange the argument and result information for a call to an unknown C++ non-static member function o...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
CGCXXABI & getCXXABI() const
const CGFunctionInfo & arrangeCXXMethodDeclaration(const CXXMethodDecl *MD)
C++ methods have some special rules and also have implicit parameters.
ASTContext & getContext() const
const CGFunctionInfo & arrangeLLVMFunctionInfo(CanQualType returnType, FnInfoOpts opts, ArrayRef< CanQualType > argTypes, FunctionType::ExtInfo info, ArrayRef< FunctionProtoType::ExtParameterInfo > paramInfos, RequiredArgs args)
"Arrange" the LLVM information for a call or type with the given signature.
const CGFunctionInfo & arrangeFreeFunctionType(CanQual< FunctionProtoType > Ty)
Arrange the argument and result information for a value of the given freestanding function type.
CanQualType DeriveThisType(const CXXRecordDecl *RD, const CXXMethodDecl *MD)
Derives the 'this' type for codegen purposes, i.e.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
bool inheritingCtorHasParams(const InheritedConstructor &Inherited, CXXCtorType Type)
Determine if a C++ inheriting constructor should have parameters matching those of its inherited cons...
bool isFuncTypeConvertible(const FunctionType *FT)
isFuncTypeConvertible - Utility to check whether a function type can be converted to an LLVM type (i....
const CGFunctionInfo & arrangeBlockFunctionCall(const CallArgList &args, const FunctionType *type)
A block function is essentially a free function with an extra implicit argument.
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
const CGFunctionInfo & arrangeUnprototypedObjCMessageSend(QualType returnType, const CallArgList &args)
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
void getExpandedTypes(QualType Ty, SmallVectorImpl< llvm::Type * >::iterator &TI)
getExpandedTypes - Expand the type
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
Objective-C methods are C functions with some implicit parameters.
llvm::LLVMContext & getLLVMContext()
const CGFunctionInfo & arrangeDeviceKernelCallerDeclaration(QualType resultType, const FunctionArgList &args)
A device kernel caller function is an offload device entry point function with a target device depend...
const CGFunctionInfo & arrangeGlobalDeclaration(GlobalDecl GD)
const CGFunctionInfo & arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD)
Arrange a thunk that takes 'this' as the first parameter followed by varargs.
const CGFunctionInfo & arrangeCXXMethodCall(const CallArgList &args, const FunctionProtoType *type, RequiredArgs required, unsigned numPrefixArgs)
Arrange a call to a C++ method, passing the given arguments.
const CGFunctionInfo & arrangeFreeFunctionCall(const CallArgList &Args, const FunctionType *Ty, bool ChainCall)
Figure out the rules for calling a function with the given formal type using the given arguments.
const CGFunctionInfo & arrangeBuiltinFunctionCall(QualType resultType, const CallArgList &args)
const CGFunctionInfo & arrangeBlockFunctionDeclaration(const FunctionProtoType *type, const FunctionArgList &args)
Block invocation functions are C functions with an implicit parameter.
unsigned ClangCallConvToLLVMCallConv(CallingConv CC)
Convert clang calling convention to LLVM callilng convention.
llvm::Type * GetFunctionTypeForVTable(GlobalDecl GD)
GetFunctionTypeForVTable - Get the LLVM function type for use in a vtable, given a CXXMethodDecl.
const CGFunctionInfo & arrangeCXXConstructorCall(const CallArgList &Args, const CXXConstructorDecl *D, CXXCtorType CtorKind, unsigned ExtraPrefixArgs, unsigned ExtraSuffixArgs, bool PassProtoArgs=true)
Arrange a call to a C++ method, passing the given arguments.
const CGFunctionInfo & arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD, QualType receiverType)
Arrange the argument and result information for the function type through which to perform a send to ...
const CGFunctionInfo & arrangeCXXStructorDeclaration(GlobalDecl GD)
const CGFunctionInfo & arrangeFunctionDeclaration(const GlobalDecl GD)
Free functions are functions that are compatible with an ordinary C function pointer type.
const CGFunctionInfo & arrangeMSCtorClosure(const CXXConstructorDecl *CD, CXXCtorType CT)
const CGFunctionInfo & arrangeCall(const CGFunctionInfo &declFI, const CallArgList &args)
Given a function info for a declaration, return the function info for a call with the given arguments...
const CGFunctionInfo & arrangeNullaryFunction()
A nullary function is a freestanding function of type 'void ()'.
A cleanup scope which generates the cleanup blocks lazily.
A saved depth on the scope stack.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
static LValue MakeAddr(Address Addr, QualType type, ASTContext &Context, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo)
Address getAddress() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
static RValue getAggregate(Address addr, bool isVolatile=false)
Convert an Address to an RValue.
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
An abstract representation of an aligned address.
CharUnits getAlignment() const
Return the alignment of this pointer.
llvm::Value * getPointer() const
static RawAddress invalid()
A class for recording the number of arguments that a function signature requires.
bool allowsOptionalArgs() const
unsigned getNumRequiredArgs() const
static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, unsigned additional)
Compute the arguments required by the given formal prototype, given that there may be some additional...
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
virtual void setCUDAKernelCallingConvention(const FunctionType *&FT) const
static void initPointerAuthFnAttributes(const PointerAuthOptions &Opts, llvm::AttrBuilder &FuncAttrs)
static void initBranchProtectionFnAttributes(const TargetInfo::BranchProtectionInfo &BPI, llvm::AttrBuilder &FuncAttrs)
virtual bool isNoProtoCallVariadic(const CodeGen::CallArgList &args, const FunctionNoProtoType *fnType) const
Determine whether a call to an unprototyped functions under the given calling convention should use t...
Complex values, per C99 6.2.5p11.
Represents the canonical version of C arrays with a specified constant size.
bool constructsVirtualBase() const
Returns true if the constructed base class is a virtual base class subobject of this declaration's cl...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Decl - This represents one declaration (or definition), e.g.
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
This represents one expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
bool isZeroLengthBitField() const
Is this a zero-length bit-field?
Represents a function declaration or definition.
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Represents a prototype with parameter type info, e.g.
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
unsigned getNumParams() const
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
ArrayRef< ExtParameterInfo > getExtParameterInfos() const
bool hasExtParameterInfos() const
Is there any interesting extra information for any of the parameters of this function type?
Wrapper for source info for functions.
A class which abstracts out some details necessary for making a call.
ExtInfo withCallingConv(CallingConv cc) const
CallingConv getCC() const
ExtInfo withProducesResult(bool producesResult) const
bool getCmseNSCall() const
bool getNoCfCheck() const
unsigned getRegParm() const
bool getNoCallerSavedRegs() const
bool getHasRegParm() const
bool getProducesResult() const
Interesting information about a specific parameter that can't simply be reflected in parameter's type...
ParameterABI getABI() const
Return the ABI treatment of this parameter.
ExtParameterInfo withIsNoEscape(bool NoEscape) const
FunctionType - C99 6.7.5.3 - Function Declarators.
ExtInfo getExtInfo() const
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
@ SME_AgnosticZAStateMask
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
QualType getReturnType() const
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
KernelReferenceKind getKernelReferenceKind() const
const Decl * getDecl() const
This class represents temporary values used to represent inout and out arguments in HLSL.
Description of a constructor that was inherited from a base class.
ConstructorUsingShadowDecl * getShadowDecl() const
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
std::vector< std::string > NoBuiltinFuncs
A list of all -fno-builtin-* function names (e.g., memset).
FPExceptionModeKind getDefaultExceptionMode() const
bool isNoBuiltinFunc(StringRef Name) const
Is this a libc/libm function that is no longer recognized as a builtin because a -fno-builtin-* optio...
bool assumeFunctionsAreConvergent() const
Represents a matrix type, as defined in the Matrix Types clang extensions.
Describes a module or submodule.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
ObjCCategoryDecl - Represents a category declaration.
ObjCIndirectCopyRestoreExpr - Represents the passing of a function argument by indirect copy-restore ...
bool shouldCopy() const
shouldCopy - True if we should do the 'copy' part of the copy-restore.
Represents an ObjC class declaration.
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
ArrayRef< ParmVarDecl * > parameters() const
bool isDirectMethod() const
True if the method is tagged as objc_direct.
QualType getReturnType() const
Represents a parameter to a function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
bool isRestrictQualified() const
Determine whether this type is restrict-qualified.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
bool isConstQualified() const
Determine whether this type is const-qualified.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
LangAS getAddressSpace() const
Represents a struct/union/class.
field_iterator field_end() const
bool isParamDestroyedInCallee() const
field_iterator field_begin() const
Base for LValueReferenceType and RValueReferenceType.
Encodes a location in the source.
UIntTy getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
Options for controlling the target.
std::vector< std::string > Features
The list of target specific features to enable or disable – this should be a list of strings starting...
std::string TuneCPU
If given, the name of the target CPU to tune code for.
std::string CPU
If given, the name of the target CPU to generate code for.
bool isIncompleteArrayType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isScalarType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isBitIntType() const
RecordDecl * castAsRecordDecl() const
bool isMemberPointerType() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isObjectType() const
Determine whether this type is an object type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isObjCRetainableType() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represents a call to the builtin function __builtin_va_arg.
Represents a variable declaration or definition.
QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const
Would the destruction of this variable have any effect, and if so, what kind?
Represents a GCC generic vector type.
Defines the clang::TargetInfo interface.
void computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI)
Compute the ABI information of a swiftcall function.
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
void computeSPIRKernelABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI)
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
void mergeDefaultFunctionDefinitionAttributes(llvm::Function &F, const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts, const TargetOptions &TargetOpts, bool WillInternalize)
Adds attributes to F according to our CodeGenOpts and LangOpts, as though we had emitted it ourselves...
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyRecord - Return true iff a structure contains only empty fields.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
bool This(InterpState &S, CodePtr OpPC)
bool Ret(InterpState &S, CodePtr &PC)
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
CXXCtorType
C++ constructor types.
@ Ctor_DefaultClosure
Default closure variant of a ctor.
@ Ctor_CopyingClosure
Copying closure variant of a ctor.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
bool isUnresolvedExceptionSpec(ExceptionSpecificationType ESpecType)
bool isInstanceMethod(const Decl *D)
@ NonNull
Values of this type can never be null.
@ OK_Ordinary
An ordinary object is located at an address in memory.
@ Vector
'vector' clause, allowed on 'loop', Combined, and 'routine' directives.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
static bool classof(const Stmt *T)
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
@ SwiftAsyncContext
This parameter (which must have pointer type) uses the special Swift asynchronous context-pointer ABI...
@ SwiftErrorResult
This parameter (which must have pointer-to-pointer type) uses the special Swift error-result ABI trea...
@ Ordinary
This parameter uses ordinary ABI rules for its type.
@ SwiftIndirectResult
This parameter (which must have pointer type) is a Swift indirect result parameter.
@ SwiftContext
This parameter (which must have pointer type) uses the special Swift context-pointer ABI treatment.
const FunctionProtoType * T
@ Dtor_Complete
Complete object dtor.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ CanPassInRegs
The argument of this type can be passed directly in registers.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
U cast(CodeGen::Address addr)
LangAS getLangASFromTargetAS(unsigned TargetAS)
__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)
Structure with information about how a bitfield should be accessed.
CharUnits StorageOffset
The offset of the bitfield storage from the start of the struct.
unsigned Offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the L...
unsigned Size
The total size of the bit-field, in bits.
unsigned StorageSize
The storage size in bits which should be used when accessing this bitfield.
Similar to AddedStructorArgs, but only notes the number of additional arguments.
llvm::Value * ToUse
A value to "use" after the writeback, or null.
LValue Source
The original argument.
Address Temporary
The temporary alloca.
const Expr * WritebackExpr
An Expression (optional) that performs the writeback with any required casting.
LValue getKnownLValue() const
RValue getKnownRValue() const
void copyInto(CodeGenFunction &CGF, Address A) const
RValue getRValue(CodeGenFunction &CGF) const
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::CallingConv::ID getRuntimeCC() const
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const
~DisableDebugLocationUpdates()
DisableDebugLocationUpdates(CodeGenFunction &CGF)
static const EHPersonality & get(CodeGenModule &CGM, const FunctionDecl *FD)
llvm::Function * objc_retainAutoreleasedReturnValue
id objc_retainAutoreleasedReturnValue(id);
llvm::Function * objc_retain
id objc_retain(id);
llvm::InlineAsm * retainAutoreleasedReturnValueMarker
A void(void) inline asm to use to mark that the return value of a call will be immediately retain.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.