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/DebugInfoMetadata.h"
42#include "llvm/IR/InlineAsm.h"
43#include "llvm/IR/IntrinsicInst.h"
44#include "llvm/IR/Intrinsics.h"
45#include "llvm/IR/Type.h"
46#include "llvm/Transforms/Utils/Local.h"
56 return llvm::CallingConv::C;
58 return llvm::CallingConv::X86_StdCall;
60 return llvm::CallingConv::X86_FastCall;
62 return llvm::CallingConv::X86_RegCall;
64 return llvm::CallingConv::X86_ThisCall;
66 return llvm::CallingConv::Win64;
68 return llvm::CallingConv::X86_64_SysV;
70 return llvm::CallingConv::ARM_AAPCS;
72 return llvm::CallingConv::ARM_AAPCS_VFP;
74 return llvm::CallingConv::Intel_OCL_BI;
77 return llvm::CallingConv::C;
80 return llvm::CallingConv::X86_VectorCall;
82 return llvm::CallingConv::AArch64_VectorCall;
84 return llvm::CallingConv::AArch64_SVE_VectorCall;
86 return llvm::CallingConv::SPIR_FUNC;
88 return CGM.getTargetCodeGenInfo().getDeviceKernelCallingConv();
90 return llvm::CallingConv::PreserveMost;
92 return llvm::CallingConv::PreserveAll;
94 return llvm::CallingConv::Swift;
96 return llvm::CallingConv::SwiftTail;
98 return llvm::CallingConv::M68k_RTD;
100 return llvm::CallingConv::PreserveNone;
104#define CC_VLS_CASE(ABI_VLEN) \
105 case CC_RISCVVLSCall_##ABI_VLEN: \
106 return llvm::CallingConv::RISCV_VLSCall_##ABI_VLEN;
131 RecTy = Context.getCanonicalTagType(RD);
133 RecTy = Context.VoidTy;
138 return Context.getPointerType(RecTy);
171 assert(paramInfos.size() <= prefixArgs);
172 assert(proto->
getNumParams() + prefixArgs <= totalArgs);
174 paramInfos.reserve(totalArgs);
177 paramInfos.resize(prefixArgs);
181 paramInfos.push_back(ParamInfo);
183 if (ParamInfo.hasPassObjectSize())
184 paramInfos.emplace_back();
187 assert(paramInfos.size() <= totalArgs &&
188 "Did we forget to insert pass_object_size args?");
190 paramInfos.resize(totalArgs);
200 if (!FPT->hasExtParameterInfos()) {
201 assert(paramInfos.empty() &&
202 "We have paramInfos, but the prototype doesn't?");
203 prefix.append(FPT->param_type_begin(), FPT->param_type_end());
207 unsigned PrefixSize = prefix.size();
211 prefix.reserve(prefix.size() + FPT->getNumParams());
213 auto ExtInfos = FPT->getExtParameterInfos();
214 assert(ExtInfos.size() == FPT->getNumParams());
215 for (
unsigned I = 0, E = FPT->getNumParams(); I != E; ++I) {
216 prefix.push_back(FPT->getParamType(I));
217 if (ExtInfos[I].hasPassObjectSize())
242 FTP->getExtInfo(), paramInfos,
Required);
252 return ::arrangeLLVMFunctionInfo(*
this,
false, argTypes,
257 bool IsTargetDefaultMSABI) {
262 if (D->
hasAttr<FastCallAttr>())
268 if (D->
hasAttr<ThisCallAttr>())
271 if (D->
hasAttr<VectorCallAttr>())
277 if (PcsAttr *PCS = D->
getAttr<PcsAttr>())
280 if (D->
hasAttr<AArch64VectorPcsAttr>())
283 if (D->
hasAttr<AArch64SVEPcsAttr>())
286 if (D->
hasAttr<DeviceKernelAttr>())
289 if (D->
hasAttr<IntelOclBiccAttr>())
298 if (D->
hasAttr<PreserveMostAttr>())
301 if (D->
hasAttr<PreserveAllAttr>())
307 if (D->
hasAttr<PreserveNoneAttr>())
310 if (D->
hasAttr<RISCVVectorCCAttr>())
313 if (RISCVVLSCCAttr *PCS = D->
getAttr<RISCVVLSCCAttr>()) {
314 switch (PCS->getVectorWidth()) {
316 llvm_unreachable(
"Invalid RISC-V VLS ABI VLEN");
317#define CC_VLS_CASE(ABI_VLEN) \
319 return CC_RISCVVLSCall_##ABI_VLEN;
354 return ::arrangeLLVMFunctionInfo(
355 *
this,
true, argTypes,
362 if (FD->
hasAttr<CUDAGlobalAttr>()) {
398 !Target.getCXXABI().hasConstructorVariants();
411 bool PassParams =
true;
413 if (
auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
416 if (
auto Inherited = CD->getInheritedConstructor())
428 if (!paramInfos.empty()) {
431 paramInfos.insert(paramInfos.begin() + 1, AddedArgs.
Prefix,
434 paramInfos.append(AddedArgs.
Suffix,
439 (PassParams && MD->isVariadic() ?
RequiredArgs(argTypes.size())
445 ? CGM.getContext().VoidPtrTy
448 argTypes, extInfo, paramInfos, required);
454 for (
auto &arg : args)
462 for (
auto &arg : args)
469 unsigned totalArgs) {
487 unsigned ExtraPrefixArgs,
unsigned ExtraSuffixArgs,
bool PassProtoArgs) {
489 for (
const auto &Arg : args)
490 ArgTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
493 unsigned TotalPrefixArgs = 1 + ExtraPrefixArgs;
498 FPT, TotalPrefixArgs + ExtraSuffixArgs)
504 ? CGM.getContext().VoidPtrTy
511 if (PassProtoArgs && FPT->hasExtParameterInfos()) {
518 ArgTypes, Info, ParamInfos,
Required);
527 if (MD->isImplicitObjectMemberFunction())
535 if (DeviceKernelAttr::isOpenCLSpelling(FD->
getAttr<DeviceKernelAttr>()) &&
538 CGM.getTargetCodeGenInfo().setOCLKernelStubCallingConvention(FT);
546 {}, noProto->getExtInfo(), {},
573 argTys.push_back(Context.getCanonicalParamType(receiverType));
575 argTys.push_back(Context.getCanonicalParamType(Context.getObjCSelType()));
577 argTys.push_back(Context.getCanonicalParamType(I->getType()));
579 I->hasAttr<NoEscapeAttr>());
580 extParamInfos.push_back(extParamInfo);
584 bool IsTargetDefaultMSABI =
590 if (
getContext().getLangOpts().ObjCAutoRefCount &&
591 MD->
hasAttr<NSReturnsRetainedAttr>())
628 assert(MD->
isVirtual() &&
"only methods have thunks");
645 ArgTys.push_back(*FTP->param_type_begin());
647 ArgTys.push_back(Context.IntTy);
648 CallingConv CC = Context.getDefaultCallingConvention(
660 unsigned numExtraRequiredArgs,
bool chainCall) {
661 assert(args.size() >= numExtraRequiredArgs);
671 if (proto->isVariadic())
674 if (proto->hasExtParameterInfos())
688 for (
const auto &arg : args)
693 paramInfos, required);
703 chainCall ? 1 : 0, chainCall);
732 for (
const auto &Arg : args)
733 argTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
773 assert(numPrefixArgs + 1 <= args.size() &&
774 "Emitting a call with less args than the required prefix?");
785 paramInfos, required);
796 assert(signature.
arg_size() <= args.size());
797 if (signature.
arg_size() == args.size())
802 if (!sigParamInfos.empty()) {
803 paramInfos.append(sigParamInfos.begin(), sigParamInfos.end());
804 paramInfos.resize(args.size());
836 assert(llvm::all_of(argTypes,
840 llvm::FoldingSetNodeID ID;
845 bool isDelegateCall =
848 info, paramInfos, required, resultType, argTypes);
850 void *insertPos =
nullptr;
851 CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, insertPos);
859 info, paramInfos, resultType, argTypes, required);
860 FunctionInfos.InsertNode(FI, insertPos);
862 bool inserted = FunctionsBeingProcessed.insert(FI).second;
864 assert(inserted &&
"Recursively being processed?");
867 if (CC == llvm::CallingConv::SPIR_KERNEL) {
874 CGM.getABIInfo().computeInfo(*FI);
885 if (I.info.canHaveCoerceToType() && I.info.getCoerceToType() ==
nullptr)
888 bool erased = FunctionsBeingProcessed.erase(FI);
890 assert(erased &&
"Not in set?");
896 bool chainCall,
bool delegateCall,
902 assert(paramInfos.empty() || paramInfos.size() == argTypes.size());
906 void *buffer =
operator new(totalSizeToAlloc<ArgInfo, ExtParameterInfo>(
907 argTypes.size() + 1, paramInfos.size()));
909 CGFunctionInfo *FI =
new (buffer) CGFunctionInfo();
910 FI->CallingConvention = llvmCC;
911 FI->EffectiveCallingConvention = llvmCC;
912 FI->ASTCallingConvention = info.
getCC();
913 FI->InstanceMethod = instanceMethod;
914 FI->ChainCall = chainCall;
915 FI->DelegateCall = delegateCall;
921 FI->Required = required;
924 FI->ArgStruct =
nullptr;
925 FI->ArgStructAlign = 0;
926 FI->NumArgs = argTypes.size();
927 FI->HasExtParameterInfos = !paramInfos.empty();
928 FI->getArgsBuffer()[0].
type = resultType;
929 FI->MaxVectorWidth = 0;
930 for (
unsigned i = 0, e = argTypes.size(); i != e; ++i)
931 FI->getArgsBuffer()[i + 1].
type = argTypes[i];
932 for (
unsigned i = 0, e = paramInfos.size(); i != e; ++i)
933 FI->getExtParameterInfosBuffer()[i] = paramInfos[i];
943struct TypeExpansion {
944 enum TypeExpansionKind {
956 const TypeExpansionKind Kind;
958 TypeExpansion(TypeExpansionKind K) : Kind(K) {}
959 virtual ~TypeExpansion() {}
962struct ConstantArrayExpansion : TypeExpansion {
966 ConstantArrayExpansion(QualType EltTy, uint64_t NumElts)
967 : TypeExpansion(TEK_ConstantArray), EltTy(EltTy), NumElts(NumElts) {}
968 static bool classof(
const TypeExpansion *TE) {
969 return TE->Kind == TEK_ConstantArray;
973struct RecordExpansion : TypeExpansion {
974 SmallVector<const CXXBaseSpecifier *, 1> Bases;
976 SmallVector<const FieldDecl *, 1> Fields;
978 RecordExpansion(SmallVector<const CXXBaseSpecifier *, 1> &&Bases,
979 SmallVector<const FieldDecl *, 1> &&Fields)
980 : TypeExpansion(TEK_Record), Bases(std::move(Bases)),
981 Fields(std::move(Fields)) {}
982 static bool classof(
const TypeExpansion *TE) {
983 return TE->Kind == TEK_Record;
987struct ComplexExpansion : TypeExpansion {
990 ComplexExpansion(QualType EltTy) : TypeExpansion(
TEK_Complex), EltTy(EltTy) {}
991 static bool classof(
const TypeExpansion *TE) {
996struct NoExpansion : TypeExpansion {
997 NoExpansion() : TypeExpansion(TEK_None) {}
998 static bool classof(
const TypeExpansion *TE) {
return TE->Kind == TEK_None; }
1002static std::unique_ptr<TypeExpansion>
1005 return std::make_unique<ConstantArrayExpansion>(AT->getElementType(),
1011 assert(!RD->hasFlexibleArrayMember() &&
1012 "Cannot expand structure with flexible array.");
1013 if (RD->isUnion()) {
1019 for (
const auto *FD : RD->fields()) {
1020 if (FD->isZeroLengthBitField())
1022 assert(!FD->isBitField() &&
1023 "Cannot expand structure with bit-field members.");
1024 CharUnits FieldSize = Context.getTypeSizeInChars(FD->getType());
1025 if (UnionSize < FieldSize) {
1026 UnionSize = FieldSize;
1031 Fields.push_back(LargestFD);
1033 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
1034 assert(!CXXRD->isDynamicClass() &&
1035 "cannot expand vtable pointers in dynamic classes");
1036 llvm::append_range(Bases, llvm::make_pointer_range(CXXRD->bases()));
1039 for (
const auto *FD : RD->fields()) {
1040 if (FD->isZeroLengthBitField())
1042 assert(!FD->isBitField() &&
1043 "Cannot expand structure with bit-field members.");
1044 Fields.push_back(FD);
1047 return std::make_unique<RecordExpansion>(std::move(Bases),
1051 return std::make_unique<ComplexExpansion>(CT->getElementType());
1053 return std::make_unique<NoExpansion>();
1058 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1061 if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1063 for (
auto BS : RExp->Bases)
1065 for (
auto FD : RExp->Fields)
1078 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1079 for (
int i = 0, n = CAExp->NumElts; i < n; i++) {
1082 }
else if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1083 for (
auto BS : RExp->Bases)
1085 for (
auto FD : RExp->Fields)
1087 }
else if (
auto CExp = dyn_cast<ComplexExpansion>(Exp.get())) {
1098 ConstantArrayExpansion *CAE,
1100 llvm::function_ref<
void(
Address)> Fn) {
1101 for (
int i = 0, n = CAE->NumElts; i < n; i++) {
1107void CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV,
1108 llvm::Function::arg_iterator &AI) {
1109 assert(LV.isSimple() &&
1110 "Unexpected non-simple lvalue during struct expansion.");
1113 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1115 *
this, CAExp, LV.getAddress(), [&](Address EltAddr) {
1116 LValue LV = MakeAddrLValue(EltAddr, CAExp->EltTy);
1117 ExpandTypeFromArgs(CAExp->EltTy, LV, AI);
1119 }
else if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1120 Address
This = LV.getAddress();
1121 for (
const CXXBaseSpecifier *BS : RExp->Bases) {
1125 false, SourceLocation());
1126 LValue SubLV = MakeAddrLValue(Base, BS->
getType());
1129 ExpandTypeFromArgs(BS->
getType(), SubLV, AI);
1131 for (
auto FD : RExp->Fields) {
1133 LValue SubLV = EmitLValueForFieldInitialization(LV, FD);
1134 ExpandTypeFromArgs(FD->getType(), SubLV, AI);
1137 auto realValue = &*AI++;
1138 auto imagValue = &*AI++;
1139 EmitStoreOfComplex(
ComplexPairTy(realValue, imagValue), LV,
true);
1144 llvm::Value *Arg = &*AI++;
1145 if (LV.isBitField()) {
1151 if (Arg->getType()->isPointerTy()) {
1152 Address
Addr = LV.getAddress();
1153 Arg = Builder.CreateBitCast(Arg,
Addr.getElementType());
1155 EmitStoreOfScalar(Arg, LV);
1160void CodeGenFunction::ExpandTypeToArgs(
1161 QualType Ty, CallArg Arg, llvm::FunctionType *IRFuncTy,
1162 SmallVectorImpl<llvm::Value *> &IRCallArgs,
unsigned &IRCallArgPos) {
1164 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1169 CallArg(convertTempToRValue(EltAddr, CAExp->EltTy, SourceLocation()),
1171 ExpandTypeToArgs(CAExp->EltTy, EltArg, IRFuncTy, IRCallArgs,
1174 }
else if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1177 for (
const CXXBaseSpecifier *BS : RExp->Bases) {
1181 false, SourceLocation());
1185 ExpandTypeToArgs(BS->
getType(), BaseArg, IRFuncTy, IRCallArgs,
1189 LValue LV = MakeAddrLValue(This, Ty);
1190 for (
auto FD : RExp->Fields) {
1192 CallArg(EmitRValueForField(LV, FD, SourceLocation()), FD->getType());
1193 ExpandTypeToArgs(FD->getType(), FldArg, IRFuncTy, IRCallArgs,
1198 IRCallArgs[IRCallArgPos++] = CV.first;
1199 IRCallArgs[IRCallArgPos++] = CV.second;
1203 assert(RV.isScalar() &&
1204 "Unexpected non-scalar rvalue during struct expansion.");
1207 llvm::Value *
V = RV.getScalarVal();
1208 if (IRCallArgPos < IRFuncTy->getNumParams() &&
1209 V->getType() != IRFuncTy->getParamType(IRCallArgPos))
1210 V = Builder.CreateBitCast(
V, IRFuncTy->getParamType(IRCallArgPos));
1212 IRCallArgs[IRCallArgPos++] =
V;
1220 const Twine &Name =
"tmp") {
1233 llvm::StructType *SrcSTy,
1237 if (SrcSTy->getNumElements() == 0)
1246 uint64_t FirstEltSize = CGF.
CGM.
getDataLayout().getTypeStoreSize(FirstElt);
1247 if (FirstEltSize < DstSize &&
1256 if (llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy))
1271 if (Val->getType() == Ty)
1277 return CGF.
Builder.CreateBitCast(Val, Ty,
"coerce.val");
1283 llvm::Type *DestIntTy = Ty;
1287 if (Val->getType() != DestIntTy) {
1289 if (DL.isBigEndian()) {
1292 uint64_t SrcSize = DL.getTypeSizeInBits(Val->getType());
1293 uint64_t DstSize = DL.getTypeSizeInBits(DestIntTy);
1295 if (SrcSize > DstSize) {
1296 Val = CGF.
Builder.CreateLShr(Val, SrcSize - DstSize,
"coerce.highbits");
1297 Val = CGF.
Builder.CreateTrunc(Val, DestIntTy,
"coerce.val.ii");
1299 Val = CGF.
Builder.CreateZExt(Val, DestIntTy,
"coerce.val.ii");
1300 Val = CGF.
Builder.CreateShl(Val, DstSize - SrcSize,
"coerce.highbits");
1304 Val = CGF.
Builder.CreateIntCast(Val, DestIntTy,
false,
"coerce.val.ii");
1309 Val = CGF.
Builder.CreateIntToPtr(Val, Ty,
"coerce.val.ip");
1330 if (llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy)) {
1332 DstSize.getFixedValue(), CGF);
1347 if (!SrcSize.isScalable() && !DstSize.isScalable() &&
1348 SrcSize.getFixedValue() >= DstSize.getFixedValue()) {
1362 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(Ty)) {
1363 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
1366 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
1367 FixedSrcTy->getElementType()->isIntegerTy(8)) {
1368 ScalableDstTy = llvm::ScalableVectorType::get(
1369 FixedSrcTy->getElementType(),
1371 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
1373 if (ScalableDstTy->getElementType() == FixedSrcTy->getElementType()) {
1375 auto *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
1376 llvm::Value *Result = CGF.
Builder.CreateInsertVector(
1377 ScalableDstTy, PoisonVec, Load, uint64_t(0),
"cast.scalable");
1379 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, Ty));
1380 if (Result->getType() != ScalableDstTy)
1381 Result = CGF.
Builder.CreateBitCast(Result, ScalableDstTy);
1382 if (Result->getType() != Ty)
1383 Result = CGF.
Builder.CreateExtractVector(Ty, Result, uint64_t(0));
1395 llvm::ConstantInt::get(CGF.
IntPtrTy, SrcSize.getKnownMinValue()));
1400 llvm::TypeSize DstSize,
1401 bool DstIsVolatile) {
1405 llvm::Type *SrcTy = Src->getType();
1406 llvm::TypeSize SrcSize =
CGM.getDataLayout().getTypeAllocSize(SrcTy);
1412 if (llvm::StructType *DstSTy =
1414 assert(!SrcSize.isScalable());
1416 SrcSize.getFixedValue(), *
this);
1420 if (SrcSize.isScalable() || SrcSize <= DstSize) {
1421 if (SrcTy->isIntegerTy() && Dst.
getElementType()->isPointerTy() &&
1425 auto *I =
Builder.CreateStore(Src, Dst, DstIsVolatile);
1427 }
else if (llvm::StructType *STy =
1428 dyn_cast<llvm::StructType>(Src->getType())) {
1431 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1433 llvm::Value *Elt =
Builder.CreateExtractValue(Src, i);
1434 auto *I =
Builder.CreateStore(Elt, EltPtr, DstIsVolatile);
1442 }
else if (SrcTy->isIntegerTy()) {
1444 llvm::Type *DstIntTy =
Builder.getIntNTy(DstSize.getFixedValue() * 8);
1461 Builder.CreateStore(Src, Tmp);
1462 auto *I =
Builder.CreateMemCpy(
1481static std::pair<llvm::Value *, bool>
1483 llvm::ScalableVectorType *FromTy, llvm::Value *
V,
1484 StringRef Name =
"") {
1487 if (FromTy->getElementType()->isIntegerTy(1) &&
1488 ToTy->getElementType() == CGF.
Builder.getInt8Ty()) {
1489 if (!FromTy->getElementCount().isKnownMultipleOf(8)) {
1490 FromTy = llvm::ScalableVectorType::get(
1491 FromTy->getElementType(),
1492 llvm::alignTo<8>(FromTy->getElementCount().getKnownMinValue()));
1493 llvm::Value *ZeroVec = llvm::Constant::getNullValue(FromTy);
1494 V = CGF.
Builder.CreateInsertVector(FromTy, ZeroVec,
V, uint64_t(0));
1496 FromTy = llvm::ScalableVectorType::get(
1497 ToTy->getElementType(),
1498 FromTy->getElementCount().getKnownMinValue() / 8);
1499 V = CGF.
Builder.CreateBitCast(
V, FromTy);
1501 if (FromTy->getElementType() == ToTy->getElementType()) {
1502 V->setName(Name +
".coerce");
1503 V = CGF.
Builder.CreateExtractVector(ToTy,
V, uint64_t(0),
"cast.fixed");
1513class ClangToLLVMArgMapping {
1514 static const unsigned InvalidIndex = ~0U;
1515 unsigned InallocaArgNo;
1517 unsigned TotalIRArgs;
1521 unsigned PaddingArgIndex;
1524 unsigned FirstArgIndex;
1525 unsigned NumberOfArgs;
1528 : PaddingArgIndex(InvalidIndex), FirstArgIndex(InvalidIndex),
1532 SmallVector<IRArgs, 8> ArgInfo;
1535 ClangToLLVMArgMapping(
const ASTContext &Context,
const CGFunctionInfo &FI,
1536 bool OnlyRequiredArgs =
false)
1537 : InallocaArgNo(InvalidIndex), SRetArgNo(InvalidIndex), TotalIRArgs(0),
1538 ArgInfo(OnlyRequiredArgs ? FI.getNumRequiredArgs() : FI.arg_size()) {
1539 construct(Context, FI, OnlyRequiredArgs);
1542 bool hasInallocaArg()
const {
return InallocaArgNo != InvalidIndex; }
1543 unsigned getInallocaArgNo()
const {
1544 assert(hasInallocaArg());
1545 return InallocaArgNo;
1548 bool hasSRetArg()
const {
return SRetArgNo != InvalidIndex; }
1549 unsigned getSRetArgNo()
const {
1550 assert(hasSRetArg());
1554 unsigned totalIRArgs()
const {
return TotalIRArgs; }
1556 bool hasPaddingArg(
unsigned ArgNo)
const {
1557 assert(ArgNo < ArgInfo.size());
1558 return ArgInfo[ArgNo].PaddingArgIndex != InvalidIndex;
1560 unsigned getPaddingArgNo(
unsigned ArgNo)
const {
1561 assert(hasPaddingArg(ArgNo));
1562 return ArgInfo[ArgNo].PaddingArgIndex;
1567 std::pair<unsigned, unsigned> getIRArgs(
unsigned ArgNo)
const {
1568 assert(ArgNo < ArgInfo.size());
1569 return std::make_pair(ArgInfo[ArgNo].FirstArgIndex,
1570 ArgInfo[ArgNo].NumberOfArgs);
1574 void construct(
const ASTContext &Context,
const CGFunctionInfo &FI,
1575 bool OnlyRequiredArgs);
1578void ClangToLLVMArgMapping::construct(
const ASTContext &Context,
1579 const CGFunctionInfo &FI,
1580 bool OnlyRequiredArgs) {
1581 unsigned IRArgNo = 0;
1582 bool SwapThisWithSRet =
false;
1587 SRetArgNo = SwapThisWithSRet ? 1 : IRArgNo++;
1595 QualType ArgType = I->type;
1596 const ABIArgInfo &AI = I->info;
1598 auto &IRArgs = ArgInfo[ArgNo];
1601 IRArgs.PaddingArgIndex = IRArgNo++;
1608 llvm::StructType *STy = dyn_cast<llvm::StructType>(AI.
getCoerceToType());
1610 IRArgs.NumberOfArgs = STy->getNumElements();
1612 IRArgs.NumberOfArgs = 1;
1618 IRArgs.NumberOfArgs = 1;
1623 IRArgs.NumberOfArgs = 0;
1633 if (IRArgs.NumberOfArgs > 0) {
1634 IRArgs.FirstArgIndex = IRArgNo;
1635 IRArgNo += IRArgs.NumberOfArgs;
1640 if (IRArgNo == 1 && SwapThisWithSRet)
1643 assert(ArgNo == ArgInfo.size());
1646 InallocaArgNo = IRArgNo++;
1648 TotalIRArgs = IRArgNo;
1656 return RI.
isIndirect() || (RI.isInAlloca() && RI.getInAllocaSRet());
1671 switch (BT->getKind()) {
1674 case BuiltinType::Float:
1676 case BuiltinType::Double:
1678 case BuiltinType::LongDouble:
1689 if (BT->getKind() == BuiltinType::LongDouble)
1690 return getTarget().useObjCFP2RetForComplexLongDouble();
1704 bool Inserted = FunctionsBeingProcessed.insert(&FI).second;
1706 assert(Inserted &&
"Recursively being processed?");
1708 llvm::Type *resultType =
nullptr;
1713 llvm_unreachable(
"Invalid ABI kind for return argument");
1725 unsigned addressSpace = CGM.getTypes().getTargetAddressSpace(ret);
1726 resultType = llvm::PointerType::get(
getLLVMContext(), addressSpace);
1742 ClangToLLVMArgMapping IRFunctionArgs(
getContext(), FI,
true);
1746 if (IRFunctionArgs.hasSRetArg()) {
1747 ArgTypes[IRFunctionArgs.getSRetArgNo()] = llvm::PointerType::get(
1752 if (IRFunctionArgs.hasInallocaArg())
1753 ArgTypes[IRFunctionArgs.getInallocaArgNo()] =
1760 for (; it != ie; ++it, ++ArgNo) {
1764 if (IRFunctionArgs.hasPaddingArg(ArgNo))
1765 ArgTypes[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
1768 unsigned FirstIRArg, NumIRArgs;
1769 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
1774 assert(NumIRArgs == 0);
1778 assert(NumIRArgs == 1);
1780 ArgTypes[FirstIRArg] = llvm::PointerType::get(
1784 assert(NumIRArgs == 1);
1785 ArgTypes[FirstIRArg] = llvm::PointerType::get(
1794 llvm::StructType *st = dyn_cast<llvm::StructType>(argType);
1796 assert(NumIRArgs == st->getNumElements());
1797 for (
unsigned i = 0, e = st->getNumElements(); i != e; ++i)
1798 ArgTypes[FirstIRArg + i] = st->getElementType(i);
1800 assert(NumIRArgs == 1);
1801 ArgTypes[FirstIRArg] = argType;
1807 auto ArgTypesIter = ArgTypes.begin() + FirstIRArg;
1809 *ArgTypesIter++ = EltTy;
1811 assert(ArgTypesIter == ArgTypes.begin() + FirstIRArg + NumIRArgs);
1816 auto ArgTypesIter = ArgTypes.begin() + FirstIRArg;
1818 assert(ArgTypesIter == ArgTypes.begin() + FirstIRArg + NumIRArgs);
1823 bool Erased = FunctionsBeingProcessed.erase(&FI);
1825 assert(Erased &&
"Not in set?");
1827 return llvm::FunctionType::get(resultType, ArgTypes, FI.
isVariadic());
1841 llvm::AttrBuilder &FuncAttrs,
1848 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
1852 FuncAttrs.addAttribute(
"aarch64_pstate_sm_enabled");
1854 FuncAttrs.addAttribute(
"aarch64_pstate_sm_compatible");
1856 FuncAttrs.addAttribute(
"aarch64_za_state_agnostic");
1860 FuncAttrs.addAttribute(
"aarch64_preserves_za");
1862 FuncAttrs.addAttribute(
"aarch64_in_za");
1864 FuncAttrs.addAttribute(
"aarch64_out_za");
1866 FuncAttrs.addAttribute(
"aarch64_inout_za");
1870 FuncAttrs.addAttribute(
"aarch64_preserves_zt0");
1872 FuncAttrs.addAttribute(
"aarch64_in_zt0");
1874 FuncAttrs.addAttribute(
"aarch64_out_zt0");
1876 FuncAttrs.addAttribute(
"aarch64_inout_zt0");
1880 const Decl *Callee) {
1886 for (
const OMPAssumeAttr *AA : Callee->specific_attrs<OMPAssumeAttr>())
1887 AA->getAssumption().split(Attrs,
",");
1890 FuncAttrs.addAttribute(llvm::AssumptionAttrKey,
1891 llvm::join(Attrs.begin(), Attrs.end(),
","));
1898 if (
const RecordType *RT =
1900 if (
const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl()))
1901 return ClassDecl->hasTrivialDestructor();
1907 const Decl *TargetDecl) {
1913 if (
Module.getLangOpts().Sanitize.has(SanitizerKind::Memory))
1917 if (!
Module.getLangOpts().CPlusPlus)
1920 if (
const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(TargetDecl)) {
1921 if (FDecl->isExternC())
1923 }
else if (
const VarDecl *VDecl = dyn_cast<VarDecl>(TargetDecl)) {
1925 if (VDecl->isExternC())
1933 return Module.getCodeGenOpts().StrictReturn ||
1934 !
Module.MayDropFunctionReturn(
Module.getContext(), RetTy) ||
1935 Module.getLangOpts().Sanitize.has(SanitizerKind::Return);
1942 llvm::DenormalMode FP32DenormalMode,
1943 llvm::AttrBuilder &FuncAttrs) {
1944 if (FPDenormalMode != llvm::DenormalMode::getDefault())
1945 FuncAttrs.addAttribute(
"denormal-fp-math", FPDenormalMode.str());
1947 if (FP32DenormalMode != FPDenormalMode && FP32DenormalMode.isValid())
1948 FuncAttrs.addAttribute(
"denormal-fp-math-f32", FP32DenormalMode.str());
1956 llvm::AttrBuilder &FuncAttrs) {
1962 StringRef Name,
bool HasOptnone,
const CodeGenOptions &CodeGenOpts,
1964 llvm::AttrBuilder &FuncAttrs) {
1967 if (CodeGenOpts.OptimizeSize)
1968 FuncAttrs.addAttribute(llvm::Attribute::OptimizeForSize);
1969 if (CodeGenOpts.OptimizeSize == 2)
1970 FuncAttrs.addAttribute(llvm::Attribute::MinSize);
1973 if (CodeGenOpts.DisableRedZone)
1974 FuncAttrs.addAttribute(llvm::Attribute::NoRedZone);
1975 if (CodeGenOpts.IndirectTlsSegRefs)
1976 FuncAttrs.addAttribute(
"indirect-tls-seg-refs");
1977 if (CodeGenOpts.NoImplicitFloat)
1978 FuncAttrs.addAttribute(llvm::Attribute::NoImplicitFloat);
1980 if (AttrOnCallSite) {
1985 FuncAttrs.addAttribute(llvm::Attribute::NoBuiltin);
1987 FuncAttrs.addAttribute(
"trap-func-name", CodeGenOpts.
TrapFuncName);
1989 switch (CodeGenOpts.getFramePointer()) {
1997 FuncAttrs.addAttribute(
"frame-pointer",
1999 CodeGenOpts.getFramePointer()));
2002 if (CodeGenOpts.LessPreciseFPMAD)
2003 FuncAttrs.addAttribute(
"less-precise-fpmad",
"true");
2005 if (CodeGenOpts.NullPointerIsValid)
2006 FuncAttrs.addAttribute(llvm::Attribute::NullPointerIsValid);
2009 FuncAttrs.addAttribute(
"no-trapping-math",
"true");
2013 if (LangOpts.NoHonorInfs)
2014 FuncAttrs.addAttribute(
"no-infs-fp-math",
"true");
2015 if (LangOpts.NoHonorNaNs)
2016 FuncAttrs.addAttribute(
"no-nans-fp-math",
"true");
2017 if (CodeGenOpts.SoftFloat)
2018 FuncAttrs.addAttribute(
"use-soft-float",
"true");
2019 FuncAttrs.addAttribute(
"stack-protector-buffer-size",
2020 llvm::utostr(CodeGenOpts.SSPBufferSize));
2021 if (LangOpts.NoSignedZero)
2022 FuncAttrs.addAttribute(
"no-signed-zeros-fp-math",
"true");
2025 const std::vector<std::string> &Recips = CodeGenOpts.
Reciprocals;
2026 if (!Recips.empty())
2027 FuncAttrs.addAttribute(
"reciprocal-estimates", llvm::join(Recips,
","));
2031 FuncAttrs.addAttribute(
"prefer-vector-width",
2034 if (CodeGenOpts.StackRealignment)
2035 FuncAttrs.addAttribute(
"stackrealign");
2036 if (CodeGenOpts.Backchain)
2037 FuncAttrs.addAttribute(
"backchain");
2038 if (CodeGenOpts.EnableSegmentedStacks)
2039 FuncAttrs.addAttribute(
"split-stack");
2041 if (CodeGenOpts.SpeculativeLoadHardening)
2042 FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
2045 switch (CodeGenOpts.getZeroCallUsedRegs()) {
2046 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Skip:
2047 FuncAttrs.removeAttribute(
"zero-call-used-regs");
2049 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPRArg:
2050 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used-gpr-arg");
2052 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPR:
2053 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used-gpr");
2055 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedArg:
2056 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used-arg");
2058 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Used:
2059 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used");
2061 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPRArg:
2062 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all-gpr-arg");
2064 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPR:
2065 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all-gpr");
2067 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllArg:
2068 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all-arg");
2070 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::All:
2071 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all");
2082 FuncAttrs.addAttribute(llvm::Attribute::Convergent);
2087 if ((LangOpts.CUDA && LangOpts.CUDAIsDevice) || LangOpts.OpenCL ||
2088 LangOpts.SYCLIsDevice) {
2089 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2092 if (CodeGenOpts.SaveRegParams && !AttrOnCallSite)
2093 FuncAttrs.addAttribute(
"save-reg-params");
2096 StringRef Var,
Value;
2098 FuncAttrs.addAttribute(Var,
Value);
2112 const llvm::Function &F,
2114 auto FFeatures = F.getFnAttribute(
"target-features");
2116 llvm::StringSet<> MergedNames;
2118 MergedFeatures.reserve(TargetOpts.
Features.size());
2120 auto AddUnmergedFeatures = [&](
auto &&FeatureRange) {
2121 for (StringRef
Feature : FeatureRange) {
2125 StringRef Name =
Feature.drop_front(1);
2126 bool Merged = !MergedNames.insert(Name).second;
2128 MergedFeatures.push_back(
Feature);
2132 if (FFeatures.isValid())
2133 AddUnmergedFeatures(llvm::split(FFeatures.getValueAsString(),
','));
2134 AddUnmergedFeatures(TargetOpts.
Features);
2136 if (!MergedFeatures.empty()) {
2137 llvm::sort(MergedFeatures);
2138 FuncAttr.addAttribute(
"target-features", llvm::join(MergedFeatures,
","));
2145 bool WillInternalize) {
2147 llvm::AttrBuilder FuncAttrs(F.getContext());
2150 if (!TargetOpts.
CPU.empty())
2151 FuncAttrs.addAttribute(
"target-cpu", TargetOpts.
CPU);
2152 if (!TargetOpts.
TuneCPU.empty())
2153 FuncAttrs.addAttribute(
"tune-cpu", TargetOpts.
TuneCPU);
2156 CodeGenOpts, LangOpts,
2159 if (!WillInternalize && F.isInterposable()) {
2164 F.addFnAttrs(FuncAttrs);
2168 llvm::AttributeMask AttrsToRemove;
2170 llvm::DenormalMode DenormModeToMerge = F.getDenormalModeRaw();
2171 llvm::DenormalMode DenormModeToMergeF32 = F.getDenormalModeF32Raw();
2172 llvm::DenormalMode Merged =
2176 if (DenormModeToMergeF32.isValid()) {
2181 if (Merged == llvm::DenormalMode::getDefault()) {
2182 AttrsToRemove.addAttribute(
"denormal-fp-math");
2183 }
else if (Merged != DenormModeToMerge) {
2185 FuncAttrs.addAttribute(
"denormal-fp-math",
2189 if (MergedF32 == llvm::DenormalMode::getDefault()) {
2190 AttrsToRemove.addAttribute(
"denormal-fp-math-f32");
2191 }
else if (MergedF32 != DenormModeToMergeF32) {
2193 FuncAttrs.addAttribute(
"denormal-fp-math-f32",
2197 F.removeFnAttrs(AttrsToRemove);
2202 F.addFnAttrs(FuncAttrs);
2205void CodeGenModule::getTrivialDefaultFunctionAttributes(
2206 StringRef Name,
bool HasOptnone,
bool AttrOnCallSite,
2207 llvm::AttrBuilder &FuncAttrs) {
2209 getLangOpts(), AttrOnCallSite,
2213void CodeGenModule::getDefaultFunctionAttributes(StringRef Name,
2215 bool AttrOnCallSite,
2216 llvm::AttrBuilder &FuncAttrs) {
2220 if (!AttrOnCallSite)
2226 if (!AttrOnCallSite)
2231 llvm::AttrBuilder &attrs) {
2232 getDefaultFunctionAttributes(
"",
false,
2234 GetCPUAndFeaturesAttributes(
GlobalDecl(), attrs);
2239 const NoBuiltinAttr *NBA =
nullptr) {
2240 auto AddNoBuiltinAttr = [&FuncAttrs](StringRef BuiltinName) {
2242 AttributeName +=
"no-builtin-";
2243 AttributeName += BuiltinName;
2244 FuncAttrs.addAttribute(AttributeName);
2248 if (LangOpts.NoBuiltin) {
2250 FuncAttrs.addAttribute(
"no-builtins");
2264 if (llvm::is_contained(NBA->builtinNames(),
"*")) {
2265 FuncAttrs.addAttribute(
"no-builtins");
2270 llvm::for_each(NBA->builtinNames(), AddNoBuiltinAttr);
2274 const llvm::DataLayout &DL,
const ABIArgInfo &AI,
2275 bool CheckCoerce =
true) {
2282 if (!DL.typeSizeEqualsStoreSize(Ty))
2289 if (llvm::TypeSize::isKnownGT(DL.getTypeSizeInBits(CoerceTy),
2290 DL.getTypeSizeInBits(Ty)))
2314 if (
const MatrixType *Matrix = dyn_cast<MatrixType>(QTy))
2316 if (
const ArrayType *Array = dyn_cast<ArrayType>(QTy))
2325 unsigned NumRequiredArgs,
unsigned ArgNo) {
2326 const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl);
2331 if (ArgNo >= NumRequiredArgs)
2335 if (ArgNo < FD->getNumParams()) {
2336 const ParmVarDecl *Param = FD->getParamDecl(ArgNo);
2337 if (Param && Param->hasAttr<MaybeUndefAttr>())
2354 if (llvm::AttributeFuncs::isNoFPClassCompatibleType(IRTy))
2357 if (llvm::StructType *ST = dyn_cast<llvm::StructType>(IRTy)) {
2359 llvm::all_of(ST->elements(),
2360 llvm::AttributeFuncs::isNoFPClassCompatibleType);
2368 llvm::FPClassTest Mask = llvm::fcNone;
2369 if (LangOpts.NoHonorInfs)
2370 Mask |= llvm::fcInf;
2371 if (LangOpts.NoHonorNaNs)
2372 Mask |= llvm::fcNan;
2378 llvm::AttributeList &Attrs) {
2379 if (Attrs.getMemoryEffects().getModRef() == llvm::ModRefInfo::NoModRef) {
2380 Attrs = Attrs.removeFnAttribute(
getLLVMContext(), llvm::Attribute::Memory);
2381 llvm::Attribute MemoryAttr = llvm::Attribute::getWithMemoryEffects(
2407 llvm::AttributeList &AttrList,
2409 bool AttrOnCallSite,
bool IsThunk) {
2417 FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2419 FuncAttrs.addAttribute(
"cmse_nonsecure_call");
2430 bool HasOptnone =
false;
2432 const NoBuiltinAttr *NBA =
nullptr;
2436 std::optional<llvm::Attribute::AttrKind> MemAttrForPtrArgs;
2437 bool AddedPotentialArgAccess =
false;
2438 auto AddPotentialArgAccess = [&]() {
2439 AddedPotentialArgAccess =
true;
2440 llvm::Attribute A = FuncAttrs.getAttribute(llvm::Attribute::Memory);
2442 FuncAttrs.addMemoryAttr(A.getMemoryEffects() |
2443 llvm::MemoryEffects::argMemOnly());
2450 if (TargetDecl->
hasAttr<ReturnsTwiceAttr>())
2451 FuncAttrs.addAttribute(llvm::Attribute::ReturnsTwice);
2452 if (TargetDecl->
hasAttr<NoThrowAttr>())
2453 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2454 if (TargetDecl->
hasAttr<NoReturnAttr>())
2455 FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2456 if (TargetDecl->
hasAttr<ColdAttr>())
2457 FuncAttrs.addAttribute(llvm::Attribute::Cold);
2458 if (TargetDecl->
hasAttr<HotAttr>())
2459 FuncAttrs.addAttribute(llvm::Attribute::Hot);
2460 if (TargetDecl->
hasAttr<NoDuplicateAttr>())
2461 FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate);
2462 if (TargetDecl->
hasAttr<ConvergentAttr>())
2463 FuncAttrs.addAttribute(llvm::Attribute::Convergent);
2465 if (
const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
2468 if (AttrOnCallSite && Fn->isReplaceableGlobalAllocationFunction()) {
2470 auto Kind = Fn->getDeclName().getCXXOverloadedOperator();
2472 (Kind == OO_New || Kind == OO_Array_New))
2473 RetAttrs.addAttribute(llvm::Attribute::NoAlias);
2476 const bool IsVirtualCall = MD && MD->
isVirtual();
2479 if (!(AttrOnCallSite && IsVirtualCall)) {
2480 if (Fn->isNoReturn())
2481 FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2482 NBA = Fn->getAttr<NoBuiltinAttr>();
2489 if (AttrOnCallSite && TargetDecl->
hasAttr<NoMergeAttr>())
2490 FuncAttrs.addAttribute(llvm::Attribute::NoMerge);
2494 if (TargetDecl->
hasAttr<ConstAttr>()) {
2495 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::none());
2496 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2499 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
2500 MemAttrForPtrArgs = llvm::Attribute::ReadNone;
2501 }
else if (TargetDecl->
hasAttr<PureAttr>()) {
2502 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
2503 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2505 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
2506 MemAttrForPtrArgs = llvm::Attribute::ReadOnly;
2507 }
else if (TargetDecl->
hasAttr<NoAliasAttr>()) {
2508 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::inaccessibleOrArgMemOnly());
2509 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2511 if (
const auto *RA = TargetDecl->
getAttr<RestrictAttr>();
2512 RA && RA->getDeallocator() ==
nullptr)
2513 RetAttrs.addAttribute(llvm::Attribute::NoAlias);
2514 if (TargetDecl->
hasAttr<ReturnsNonNullAttr>() &&
2515 !CodeGenOpts.NullPointerIsValid)
2516 RetAttrs.addAttribute(llvm::Attribute::NonNull);
2517 if (TargetDecl->
hasAttr<AnyX86NoCallerSavedRegistersAttr>())
2518 FuncAttrs.addAttribute(
"no_caller_saved_registers");
2519 if (TargetDecl->
hasAttr<AnyX86NoCfCheckAttr>())
2520 FuncAttrs.addAttribute(llvm::Attribute::NoCfCheck);
2521 if (TargetDecl->
hasAttr<LeafAttr>())
2522 FuncAttrs.addAttribute(llvm::Attribute::NoCallback);
2523 if (TargetDecl->
hasAttr<BPFFastCallAttr>())
2524 FuncAttrs.addAttribute(
"bpf_fastcall");
2526 HasOptnone = TargetDecl->
hasAttr<OptimizeNoneAttr>();
2527 if (
auto *AllocSize = TargetDecl->
getAttr<AllocSizeAttr>()) {
2528 std::optional<unsigned> NumElemsParam;
2529 if (AllocSize->getNumElemsParam().isValid())
2530 NumElemsParam = AllocSize->getNumElemsParam().getLLVMIndex();
2531 FuncAttrs.addAllocSizeAttr(AllocSize->getElemSizeParam().getLLVMIndex(),
2535 if (DeviceKernelAttr::isOpenCLSpelling(
2536 TargetDecl->
getAttr<DeviceKernelAttr>()) &&
2543 FuncAttrs.addAttribute(
"uniform-work-group-size",
"true");
2550 FuncAttrs.addAttribute(
2551 "uniform-work-group-size",
2552 llvm::toStringRef(
getLangOpts().OffloadUniformBlock));
2556 if (TargetDecl->
hasAttr<CUDAGlobalAttr>() &&
2558 FuncAttrs.addAttribute(
"uniform-work-group-size",
"true");
2560 if (TargetDecl->
hasAttr<ArmLocallyStreamingAttr>())
2561 FuncAttrs.addAttribute(
"aarch64_pstate_sm_body");
2563 if (
auto *ModularFormat = TargetDecl->
getAttr<ModularFormatAttr>()) {
2564 FormatAttr *Format = TargetDecl->
getAttr<FormatAttr>();
2565 StringRef
Type = Format->getType()->getName();
2566 std::string FormatIdx = std::to_string(Format->getFormatIdx());
2567 std::string FirstArg = std::to_string(Format->getFirstArg());
2569 Type, FormatIdx, FirstArg,
2570 ModularFormat->getModularImplFn()->getName(),
2571 ModularFormat->getImplName()};
2572 llvm::append_range(Args, ModularFormat->aspects());
2573 FuncAttrs.addAttribute(
"modular-format", llvm::join(Args,
","));
2586 getDefaultFunctionAttributes(Name, HasOptnone, AttrOnCallSite, FuncAttrs);
2591 if (TargetDecl->
hasAttr<NoSpeculativeLoadHardeningAttr>())
2592 FuncAttrs.removeAttribute(llvm::Attribute::SpeculativeLoadHardening);
2593 if (TargetDecl->
hasAttr<SpeculativeLoadHardeningAttr>())
2594 FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
2595 if (TargetDecl->
hasAttr<NoSplitStackAttr>())
2596 FuncAttrs.removeAttribute(
"split-stack");
2597 if (TargetDecl->
hasAttr<ZeroCallUsedRegsAttr>()) {
2600 TargetDecl->
getAttr<ZeroCallUsedRegsAttr>()->getZeroCallUsedRegs();
2601 FuncAttrs.removeAttribute(
"zero-call-used-regs");
2602 FuncAttrs.addAttribute(
2603 "zero-call-used-regs",
2604 ZeroCallUsedRegsAttr::ConvertZeroCallUsedRegsKindToStr(Kind));
2611 if (CodeGenOpts.NoPLT) {
2612 if (
auto *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
2613 if (!Fn->isDefined() && !AttrOnCallSite) {
2614 FuncAttrs.addAttribute(llvm::Attribute::NonLazyBind);
2619 if (TargetDecl->
hasAttr<NoConvergentAttr>())
2620 FuncAttrs.removeAttribute(llvm::Attribute::Convergent);
2625 if (TargetDecl && CodeGenOpts.UniqueInternalLinkageNames) {
2626 if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
2627 if (!FD->isExternallyVisible())
2628 FuncAttrs.addAttribute(
"sample-profile-suffix-elision-policy",
2635 if (!AttrOnCallSite) {
2636 if (TargetDecl && TargetDecl->
hasAttr<CmseNSEntryAttr>())
2637 FuncAttrs.addAttribute(
"cmse_nonsecure_entry");
2640 auto shouldDisableTailCalls = [&] {
2642 if (CodeGenOpts.DisableTailCalls)
2648 if (TargetDecl->
hasAttr<DisableTailCallsAttr>() ||
2649 TargetDecl->
hasAttr<AnyX86InterruptAttr>())
2652 if (CodeGenOpts.NoEscapingBlockTailCalls) {
2653 if (
const auto *BD = dyn_cast<BlockDecl>(TargetDecl))
2654 if (!BD->doesNotEscape())
2660 if (shouldDisableTailCalls())
2661 FuncAttrs.addAttribute(
"disable-tail-calls",
"true");
2666 static const llvm::StringSet<> ReturnsTwiceFn{
2667 "_setjmpex",
"setjmp",
"_setjmp",
"vfork",
2668 "sigsetjmp",
"__sigsetjmp",
"savectx",
"getcontext"};
2669 if (ReturnsTwiceFn.contains(Name))
2670 FuncAttrs.addAttribute(llvm::Attribute::ReturnsTwice);
2674 GetCPUAndFeaturesAttributes(CalleeInfo.
getCalleeDecl(), FuncAttrs);
2677 if (!MSHotPatchFunctions.empty()) {
2678 bool IsHotPatched = llvm::binary_search(MSHotPatchFunctions, Name);
2680 FuncAttrs.addAttribute(
"marked_for_windows_hot_patching");
2685 if (CodeGenOpts.isLoaderReplaceableFunctionName(Name))
2686 FuncAttrs.addAttribute(
"loader-replaceable");
2689 ClangToLLVMArgMapping IRFunctionArgs(
getContext(), FI);
2696 if (CodeGenOpts.EnableNoundefAttrs &&
2700 RetAttrs.addAttribute(llvm::Attribute::NoUndef);
2706 RetAttrs.addAttribute(llvm::Attribute::SExt);
2708 RetAttrs.addAttribute(llvm::Attribute::ZExt);
2710 RetAttrs.addAttribute(llvm::Attribute::NoExt);
2715 RetAttrs.addAttribute(llvm::Attribute::InReg);
2727 AddPotentialArgAccess();
2736 llvm_unreachable(
"Invalid ABI kind for return argument");
2744 RetAttrs.addDereferenceableAttr(
2746 if (
getTypes().getTargetAddressSpace(PTy) == 0 &&
2747 !CodeGenOpts.NullPointerIsValid)
2748 RetAttrs.addAttribute(llvm::Attribute::NonNull);
2750 llvm::Align Alignment =
2752 RetAttrs.addAlignmentAttr(Alignment);
2757 bool hasUsedSRet =
false;
2761 if (IRFunctionArgs.hasSRetArg()) {
2763 SRETAttrs.addStructRetAttr(
getTypes().ConvertTypeForMem(RetTy));
2764 SRETAttrs.addAttribute(llvm::Attribute::Writable);
2765 SRETAttrs.addAttribute(llvm::Attribute::DeadOnUnwind);
2768 SRETAttrs.addAttribute(llvm::Attribute::InReg);
2770 ArgAttrs[IRFunctionArgs.getSRetArgNo()] =
2775 if (IRFunctionArgs.hasInallocaArg()) {
2778 ArgAttrs[IRFunctionArgs.getInallocaArgNo()] =
2787 auto IRArgs = IRFunctionArgs.getIRArgs(0);
2789 assert(IRArgs.second == 1 &&
"Expected only a single `this` pointer.");
2795 if (!CodeGenOpts.NullPointerIsValid &&
2797 Attrs.addAttribute(llvm::Attribute::NonNull);
2804 Attrs.addDereferenceableOrNullAttr(
2810 llvm::Align Alignment =
2814 Attrs.addAlignmentAttr(Alignment);
2816 ArgAttrs[IRArgs.first] = llvm::AttributeSet::get(
getLLVMContext(), Attrs);
2821 I != E; ++I, ++ArgNo) {
2827 if (IRFunctionArgs.hasPaddingArg(ArgNo)) {
2829 ArgAttrs[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
2832 .addAttribute(llvm::Attribute::InReg));
2837 if (CodeGenOpts.EnableNoundefAttrs &&
2839 Attrs.addAttribute(llvm::Attribute::NoUndef);
2848 Attrs.addAttribute(llvm::Attribute::SExt);
2850 Attrs.addAttribute(llvm::Attribute::ZExt);
2852 Attrs.addAttribute(llvm::Attribute::NoExt);
2857 Attrs.addAttribute(llvm::Attribute::Nest);
2859 Attrs.addAttribute(llvm::Attribute::InReg);
2860 Attrs.addStackAlignmentAttr(llvm::MaybeAlign(AI.
getDirectAlign()));
2867 Attrs.addAttribute(llvm::Attribute::InReg);
2879 Attrs.addByValAttr(
getTypes().ConvertTypeForMem(ParamType));
2887 Attrs.addAttribute(llvm::Attribute::DeadOnReturn);
2892 if (CodeGenOpts.PassByValueIsNoAlias &&
Decl &&
2893 Decl->getArgPassingRestrictions() ==
2897 Attrs.addAttribute(llvm::Attribute::NoAlias);
2922 AddPotentialArgAccess();
2927 Attrs.addByRefAttr(
getTypes().ConvertTypeForMem(ParamType));
2938 AddPotentialArgAccess();
2946 if (
getTypes().getTargetAddressSpace(PTy) == 0 &&
2947 !CodeGenOpts.NullPointerIsValid)
2948 Attrs.addAttribute(llvm::Attribute::NonNull);
2950 llvm::Align Alignment =
2952 Attrs.addAlignmentAttr(Alignment);
2961 DeviceKernelAttr::isOpenCLSpelling(
2962 TargetDecl->
getAttr<DeviceKernelAttr>()) &&
2966 llvm::Align Alignment =
2968 Attrs.addAlignmentAttr(Alignment);
2975 Attrs.addAttribute(llvm::Attribute::NoAlias);
2984 Attrs.addStructRetAttr(
getTypes().ConvertTypeForMem(ParamType));
2989 Attrs.addAttribute(llvm::Attribute::NoAlias);
2993 if (!PTy->isIncompleteType() && PTy->isConstantSizeType()) {
2994 auto info =
getContext().getTypeInfoInChars(PTy);
2995 Attrs.addDereferenceableAttr(info.Width.getQuantity());
2996 Attrs.addAlignmentAttr(info.Align.getAsAlign());
3002 Attrs.addAttribute(llvm::Attribute::SwiftError);
3006 Attrs.addAttribute(llvm::Attribute::SwiftSelf);
3010 Attrs.addAttribute(llvm::Attribute::SwiftAsync);
3015 Attrs.addCapturesAttr(llvm::CaptureInfo::none());
3017 if (Attrs.hasAttributes()) {
3018 unsigned FirstIRArg, NumIRArgs;
3019 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
3020 for (
unsigned i = 0; i < NumIRArgs; i++)
3021 ArgAttrs[FirstIRArg + i] = ArgAttrs[FirstIRArg + i].addAttributes(
3028 if (AddedPotentialArgAccess && MemAttrForPtrArgs) {
3032 I != E; ++I, ++ArgNo) {
3033 if (I->info.isDirect() || I->info.isExpand() ||
3034 I->info.isCoerceAndExpand()) {
3035 unsigned FirstIRArg, NumIRArgs;
3036 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
3037 for (
unsigned i = FirstIRArg; i < FirstIRArg + NumIRArgs; ++i) {
3047 AttrList = llvm::AttributeList::get(
3056 llvm::Value *value) {
3057 llvm::Type *varType = CGF.
ConvertType(var->getType());
3061 if (value->getType() == varType)
3064 assert((varType->isIntegerTy() || varType->isFloatingPointTy()) &&
3065 "unexpected promotion type");
3068 return CGF.
Builder.CreateTrunc(value, varType,
"arg.unpromote");
3070 return CGF.
Builder.CreateFPCast(value, varType,
"arg.unpromote");
3076 QualType ArgType,
unsigned ArgNo) {
3084 if (!ArgType->isAnyPointerType() && !ArgType->isBlockPointerType())
3088 if (
auto ParmNNAttr = PVD->
getAttr<NonNullAttr>())
3095 if (NNAttr->isNonNull(ArgNo))
3102struct CopyBackSwiftError final : EHScopeStack::Cleanup {
3105 CopyBackSwiftError(Address temp, Address arg) : Temp(temp), Arg(
arg) {}
3106 void Emit(CodeGenFunction &CGF, Flags flags)
override {
3125 if (FD->hasImplicitReturnZero()) {
3126 QualType RetTy = FD->getReturnType().getUnqualifiedType();
3127 llvm::Type *LLVMTy =
CGM.getTypes().ConvertType(RetTy);
3128 llvm::Constant *
Zero = llvm::Constant::getNullValue(LLVMTy);
3136 ClangToLLVMArgMapping IRFunctionArgs(
CGM.getContext(), FI);
3137 assert(Fn->arg_size() == IRFunctionArgs.totalIRArgs());
3142 if (IRFunctionArgs.hasInallocaArg())
3143 ArgStruct =
Address(Fn->getArg(IRFunctionArgs.getInallocaArgNo()),
3147 if (IRFunctionArgs.hasSRetArg()) {
3148 auto AI = Fn->getArg(IRFunctionArgs.getSRetArgNo());
3149 AI->setName(
"agg.result");
3150 AI->addAttr(llvm::Attribute::NoAlias);
3157 ArgVals.reserve(Args.size());
3163 assert(FI.
arg_size() == Args.size() &&
3164 "Mismatch between function signature & arguments.");
3167 for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); i != e;
3168 ++i, ++info_it, ++ArgNo) {
3181 unsigned FirstIRArg, NumIRArgs;
3182 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
3186 assert(NumIRArgs == 0);
3199 assert(NumIRArgs == 1);
3222 llvm::ConstantInt::get(
IntPtrTy, Size.getQuantity()));
3223 ParamAddr = AlignedTemp;
3240 auto AI = Fn->getArg(FirstIRArg);
3248 assert(NumIRArgs == 1);
3250 if (
const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(Arg)) {
3253 PVD->getFunctionScopeIndex()) &&
3254 !
CGM.getCodeGenOpts().NullPointerIsValid)
3255 AI->addAttr(llvm::Attribute::NonNull);
3257 QualType OTy = PVD->getOriginalType();
3258 if (
const auto *ArrTy =
getContext().getAsConstantArrayType(OTy)) {
3264 QualType ETy = ArrTy->getElementType();
3265 llvm::Align Alignment =
3266 CGM.getNaturalTypeAlignment(ETy).getAsAlign();
3268 .addAlignmentAttr(Alignment));
3269 uint64_t ArrSize = ArrTy->getZExtSize();
3273 Attrs.addDereferenceableAttr(
3274 getContext().getTypeSizeInChars(ETy).getQuantity() *
3276 AI->addAttrs(Attrs);
3277 }
else if (
getContext().getTargetInfo().getNullPointerValue(
3279 !
CGM.getCodeGenOpts().NullPointerIsValid) {
3280 AI->addAttr(llvm::Attribute::NonNull);
3283 }
else if (
const auto *ArrTy =
3289 QualType ETy = ArrTy->getElementType();
3290 llvm::Align Alignment =
3291 CGM.getNaturalTypeAlignment(ETy).getAsAlign();
3293 .addAlignmentAttr(Alignment));
3294 if (!
getTypes().getTargetAddressSpace(ETy) &&
3295 !
CGM.getCodeGenOpts().NullPointerIsValid)
3296 AI->addAttr(llvm::Attribute::NonNull);
3301 const auto *AVAttr = PVD->getAttr<AlignValueAttr>();
3304 AVAttr = TOTy->getDecl()->getAttr<AlignValueAttr>();
3305 if (AVAttr && !
SanOpts.has(SanitizerKind::Alignment)) {
3309 llvm::ConstantInt *AlignmentCI =
3311 uint64_t AlignmentInt =
3312 AlignmentCI->getLimitedValue(llvm::Value::MaximumAlignment);
3313 if (AI->getParamAlign().valueOrOne() < AlignmentInt) {
3314 AI->removeAttr(llvm::Attribute::AttrKind::Alignment);
3316 .addAlignmentAttr(llvm::Align(AlignmentInt)));
3323 AI->addAttr(llvm::Attribute::NoAlias);
3331 assert(NumIRArgs == 1);
3335 llvm::Value *
V = AI;
3343 V, pointeeTy,
getContext().getTypeAlignInChars(pointeeTy));
3344 llvm::Value *incomingErrorValue =
Builder.CreateLoad(arg);
3345 Builder.CreateStore(incomingErrorValue, temp);
3366 if (
V->getType() != LTy)
3377 if (
auto *VecTyTo = dyn_cast<llvm::FixedVectorType>(
ConvertType(Ty))) {
3378 llvm::Value *ArgVal = Fn->getArg(FirstIRArg);
3379 if (
auto *VecTyFrom =
3380 dyn_cast<llvm::ScalableVectorType>(ArgVal->getType())) {
3382 *
this, VecTyTo, VecTyFrom, ArgVal, Arg->
getName());
3384 assert(NumIRArgs == 1);
3391 llvm::StructType *STy =
3402 STy->getNumElements() > 1) {
3403 llvm::TypeSize StructSize =
CGM.getDataLayout().getTypeAllocSize(STy);
3404 llvm::TypeSize PtrElementSize =
3406 if (StructSize.isScalable()) {
3407 assert(STy->containsHomogeneousScalableVectorTypes() &&
3408 "ABI only supports structure with homogeneous scalable vector "
3410 assert(StructSize == PtrElementSize &&
3411 "Only allow non-fractional movement of structure with"
3412 "homogeneous scalable vector type");
3413 assert(STy->getNumElements() == NumIRArgs);
3415 llvm::Value *LoadedStructValue = llvm::PoisonValue::get(STy);
3416 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
3417 auto *AI = Fn->getArg(FirstIRArg + i);
3418 AI->setName(Arg->
getName() +
".coerce" + Twine(i));
3420 Builder.CreateInsertValue(LoadedStructValue, AI, i);
3423 Builder.CreateStore(LoadedStructValue, Ptr);
3425 uint64_t SrcSize = StructSize.getFixedValue();
3426 uint64_t DstSize = PtrElementSize.getFixedValue();
3429 if (SrcSize <= DstSize) {
3436 assert(STy->getNumElements() == NumIRArgs);
3437 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
3438 auto AI = Fn->getArg(FirstIRArg + i);
3439 AI->setName(Arg->
getName() +
".coerce" + Twine(i));
3441 Builder.CreateStore(AI, EltPtr);
3444 if (SrcSize > DstSize) {
3445 Builder.CreateMemCpy(Ptr, AddrToStoreInto, DstSize);
3450 assert(NumIRArgs == 1);
3451 auto AI = Fn->getArg(FirstIRArg);
3452 AI->setName(Arg->
getName() +
".coerce");
3455 llvm::TypeSize::getFixed(
3456 getContext().getTypeSizeInChars(Ty).getQuantity() -
3481 auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
3485 unsigned argIndex = FirstIRArg;
3486 unsigned unpaddedIndex = 0;
3487 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
3488 llvm::Type *eltType = coercionType->getElementType(i);
3492 auto eltAddr =
Builder.CreateStructGEP(alloca, i);
3493 llvm::Value *elt = Fn->getArg(argIndex++);
3495 auto paramType = unpaddedStruct
3496 ? unpaddedStruct->getElementType(unpaddedIndex++)
3497 : unpaddedCoercionType;
3499 if (
auto *VecTyTo = dyn_cast<llvm::FixedVectorType>(eltType)) {
3500 if (
auto *VecTyFrom = dyn_cast<llvm::ScalableVectorType>(paramType)) {
3503 *
this, VecTyTo, VecTyFrom, elt, elt->getName());
3504 assert(Extracted &&
"Unexpected scalable to fixed vector coercion");
3507 Builder.CreateStore(elt, eltAddr);
3509 assert(argIndex == FirstIRArg + NumIRArgs);
3521 auto FnArgIter = Fn->arg_begin() + FirstIRArg;
3522 ExpandTypeFromArgs(Ty, LV, FnArgIter);
3523 assert(FnArgIter == Fn->arg_begin() + FirstIRArg + NumIRArgs);
3524 for (
unsigned i = 0, e = NumIRArgs; i != e; ++i) {
3525 auto AI = Fn->getArg(FirstIRArg + i);
3526 AI->setName(Arg->
getName() +
"." + Twine(i));
3532 auto *AI = Fn->getArg(FirstIRArg);
3533 AI->setName(Arg->
getName() +
".target_coerce");
3537 CGM.getABIInfo().createCoercedStore(AI, Ptr, ArgI,
false, *
this);
3551 assert(NumIRArgs == 0);
3563 if (
getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) {
3564 for (
int I = Args.size() - 1; I >= 0; --I)
3567 for (
unsigned I = 0, E = Args.size(); I != E; ++I)
3573 while (insn->use_empty()) {
3574 llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(insn);
3580 bitcast->eraseFromParent();
3586 llvm::Value *result) {
3588 llvm::BasicBlock *BB = CGF.
Builder.GetInsertBlock();
3591 if (&BB->back() != result)
3594 llvm::Type *resultType = result->getType();
3603 while (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(generator)) {
3609 if (generator->getNextNode() != bitcast)
3612 InstsToKill.push_back(bitcast);
3619 llvm::CallInst *call = dyn_cast<llvm::CallInst>(generator);
3623 bool doRetainAutorelease;
3626 doRetainAutorelease =
true;
3627 }
else if (call->getCalledOperand() ==
3629 doRetainAutorelease =
false;
3637 llvm::Instruction *prev = call->getPrevNode();
3640 prev = prev->getPrevNode();
3646 InstsToKill.push_back(prev);
3652 result = call->getArgOperand(0);
3653 InstsToKill.push_back(call);
3657 while (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(result)) {
3658 if (!bitcast->hasOneUse())
3660 InstsToKill.push_back(bitcast);
3661 result = bitcast->getOperand(0);
3665 for (
auto *I : InstsToKill)
3666 I->eraseFromParent();
3669 if (doRetainAutorelease)
3673 return CGF.
Builder.CreateBitCast(result, resultType);
3678 llvm::Value *result) {
3681 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurCodeDecl);
3690 llvm::CallInst *retainCall = dyn_cast<llvm::CallInst>(result);
3691 if (!retainCall || retainCall->getCalledOperand() !=
3696 llvm::Value *retainedValue = retainCall->getArgOperand(0);
3697 llvm::LoadInst *load =
3698 dyn_cast<llvm::LoadInst>(retainedValue->stripPointerCasts());
3699 if (!load || load->isAtomic() || load->isVolatile() ||
3706 llvm::Type *resultType = result->getType();
3708 assert(retainCall->use_empty());
3709 retainCall->eraseFromParent();
3712 return CGF.
Builder.CreateBitCast(load, resultType);
3719 llvm::Value *result) {
3742 auto GetStoreIfValid = [&CGF,
3743 ReturnValuePtr](llvm::User *
U) -> llvm::StoreInst * {
3744 auto *SI = dyn_cast<llvm::StoreInst>(
U);
3745 if (!SI || SI->getPointerOperand() != ReturnValuePtr ||
3751 assert(!SI->isAtomic() &&
3759 if (!ReturnValuePtr->hasOneUse()) {
3760 llvm::BasicBlock *IP = CGF.
Builder.GetInsertBlock();
3766 const llvm::Instruction *LoadIntoFakeUse =
nullptr;
3767 for (llvm::Instruction &I : llvm::reverse(*IP)) {
3771 if (LoadIntoFakeUse == &I)
3775 if (
auto *II = dyn_cast<llvm::IntrinsicInst>(&I)) {
3776 if (II->getIntrinsicID() == llvm::Intrinsic::lifetime_end)
3779 if (II->getIntrinsicID() == llvm::Intrinsic::fake_use) {
3780 LoadIntoFakeUse = dyn_cast<llvm::Instruction>(II->getArgOperand(0));
3784 return GetStoreIfValid(&I);
3789 llvm::StoreInst *store = GetStoreIfValid(ReturnValuePtr->user_back());
3795 llvm::BasicBlock *StoreBB = store->getParent();
3796 llvm::BasicBlock *IP = CGF.
Builder.GetInsertBlock();
3798 while (IP != StoreBB) {
3799 if (!SeenBBs.insert(IP).second || !(IP = IP->getSinglePredecessor()))
3815 int BitWidth,
int CharWidth) {
3816 assert(CharWidth <= 64);
3817 assert(
static_cast<unsigned>(BitWidth) <= Bits.size() * CharWidth);
3820 if (BitOffset >= CharWidth) {
3821 Pos += BitOffset / CharWidth;
3822 BitOffset = BitOffset % CharWidth;
3825 const uint64_t
Used = (uint64_t(1) << CharWidth) - 1;
3826 if (BitOffset + BitWidth >= CharWidth) {
3827 Bits[Pos++] |= (
Used << BitOffset) &
Used;
3828 BitWidth -= CharWidth - BitOffset;
3832 while (BitWidth >= CharWidth) {
3834 BitWidth -= CharWidth;
3838 Bits[Pos++] |= (
Used >> (CharWidth - BitWidth)) << BitOffset;
3846 int StorageSize,
int BitOffset,
int BitWidth,
3847 int CharWidth,
bool BigEndian) {
3850 setBitRange(TmpBits, BitOffset, BitWidth, CharWidth);
3853 std::reverse(TmpBits.begin(), TmpBits.end());
3855 for (uint64_t
V : TmpBits)
3856 Bits[StorageOffset++] |=
V;
3859static void setUsedBits(CodeGenModule &, QualType,
int,
3860 SmallVectorImpl<uint64_t> &);
3871 const RecordDecl *RD = RTy->getDecl()->getDefinition();
3902 QualType ETy = Context.getBaseElementType(ATy);
3903 int Size = Context.getTypeSizeInChars(ETy).getQuantity();
3907 for (
int I = 0, N = Context.getConstantArrayElementCount(ATy); I < N; ++I) {
3908 auto Src = TmpBits.begin();
3909 auto Dst = Bits.begin() + Offset + I * Size;
3910 for (
int J = 0; J < Size; ++J)
3923 if (
const auto *ATy = Context.getAsConstantArrayType(QTy))
3926 int Size = Context.getTypeSizeInChars(QTy).getQuantity();
3930 std::fill_n(Bits.begin() + Offset, Size,
3931 (uint64_t(1) << Context.getCharWidth()) - 1);
3935 int Pos,
int Size,
int CharWidth,
3940 for (
auto P = Bits.begin() + Pos, E = Bits.begin() + Pos + Size; P != E;
3942 Mask = (Mask << CharWidth) | *P;
3944 auto P = Bits.begin() + Pos + Size, End = Bits.begin() + Pos;
3946 Mask = (Mask << CharWidth) | *--P;
3955 llvm::IntegerType *ITy,
3957 assert(Src->getType() == ITy);
3958 assert(ITy->getScalarSizeInBits() <= 64);
3960 const llvm::DataLayout &DataLayout =
CGM.getDataLayout();
3961 int Size = DataLayout.getTypeStoreSize(ITy);
3965 int CharWidth =
CGM.getContext().getCharWidth();
3969 return Builder.CreateAnd(Src, Mask,
"cmse.clear");
3975 llvm::ArrayType *ATy,
3977 const llvm::DataLayout &DataLayout =
CGM.getDataLayout();
3978 int Size = DataLayout.getTypeStoreSize(ATy);
3983 int CharWidth =
CGM.getContext().getCharWidth();
3985 ATy->getArrayElementType()->getScalarSizeInBits() / CharWidth;
3987 llvm::Value *R = llvm::PoisonValue::get(ATy);
3988 for (
int I = 0, N = ATy->getArrayNumElements(); I != N; ++I) {
3990 DataLayout.isBigEndian());
3991 MaskIndex += CharsPerElt;
3992 llvm::Value *T0 =
Builder.CreateExtractValue(Src, I);
3993 llvm::Value *T1 =
Builder.CreateAnd(T0, Mask,
"cmse.clear");
3994 R =
Builder.CreateInsertValue(R, T1, I);
4002 uint64_t RetKeyInstructionsSourceAtom) {
4017 auto *I =
Builder.CreateRetVoid();
4018 if (RetKeyInstructionsSourceAtom)
4025 llvm::DebugLoc RetDbgLoc;
4026 llvm::Value *RV =
nullptr;
4036 llvm::Function::arg_iterator EI =
CurFn->arg_end();
4038 llvm::Value *ArgStruct = &*EI;
4039 llvm::Value *SRet =
Builder.CreateStructGEP(
4048 auto AI =
CurFn->arg_begin();
4066 CGM.getNaturalTypeAlignment(RetTy, &BaseInfo, &TBAAInfo);
4093 RetDbgLoc = SI->getDebugLoc();
4095 RV = SI->getValueOperand();
4096 SI->eraseFromParent();
4119 if (
auto *FD = dyn_cast<FunctionDecl>(
CurCodeDecl))
4120 RT = FD->getReturnType();
4121 else if (
auto *MD = dyn_cast<ObjCMethodDecl>(
CurCodeDecl))
4122 RT = MD->getReturnType();
4124 RT =
BlockInfo->BlockExpression->getFunctionType()->getReturnType();
4126 llvm_unreachable(
"Unexpected function/method type");
4142 auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
4147 unsigned unpaddedIndex = 0;
4148 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
4149 auto coercedEltType = coercionType->getElementType(i);
4153 auto eltAddr =
Builder.CreateStructGEP(addr, i);
4156 unpaddedStruct ? unpaddedStruct->getElementType(unpaddedIndex++)
4157 : unpaddedCoercionType,
4159 results.push_back(elt);
4163 if (results.size() == 1) {
4171 RV = llvm::PoisonValue::get(returnType);
4172 for (
unsigned i = 0, e = results.size(); i != e; ++i) {
4173 RV =
Builder.CreateInsertValue(RV, results[i], i);
4180 RV =
CGM.getABIInfo().createCoercedLoad(
V, RetAI, *
this);
4185 llvm_unreachable(
"Invalid ABI kind for return argument");
4188 llvm::Instruction *Ret;
4194 auto *ITy = dyn_cast<llvm::IntegerType>(RV->getType());
4201 Ret =
Builder.CreateRetVoid();
4205 Ret->setDebugLoc(std::move(RetDbgLoc));
4207 llvm::Value *Backup = RV ? Ret->getOperand(0) :
nullptr;
4208 if (RetKeyInstructionsSourceAtom)
4224 ReturnsNonNullAttr *RetNNAttr =
nullptr;
4225 if (
SanOpts.has(SanitizerKind::ReturnsNonnullAttribute))
4226 RetNNAttr =
CurCodeDecl->getAttr<ReturnsNonNullAttr>();
4228 if (!RetNNAttr && !requiresReturnValueNullabilityCheck())
4236 assert(!requiresReturnValueNullabilityCheck() &&
4237 "Cannot check nullability and the nonnull attribute");
4238 AttrLoc = RetNNAttr->getLocation();
4239 CheckKind = SanitizerKind::SO_ReturnsNonnullAttribute;
4240 Handler = SanitizerHandler::NonnullReturn;
4242 if (
auto *DD = dyn_cast<DeclaratorDecl>(
CurCodeDecl))
4243 if (
auto *TSI = DD->getTypeSourceInfo())
4245 AttrLoc = FTL.getReturnLoc().findNullabilityLoc();
4246 CheckKind = SanitizerKind::SO_NullabilityReturn;
4247 Handler = SanitizerHandler::NullabilityReturn;
4256 llvm::Value *SLocPtr =
Builder.CreateLoad(ReturnLocation,
"return.sloc.load");
4257 llvm::Value *CanNullCheck =
Builder.CreateIsNotNull(SLocPtr);
4258 if (requiresReturnValueNullabilityCheck())
4260 Builder.CreateAnd(CanNullCheck, RetValNullabilityPrecondition);
4261 Builder.CreateCondBr(CanNullCheck, Check, NoCheck);
4267 llvm::Value *DynamicData[] = {SLocPtr};
4268 EmitCheck(std::make_pair(
Cond, CheckKind), Handler, StaticData, DynamicData);
4287 llvm::Type *IRPtrTy = llvm::PointerType::getUnqual(CGF.
getLLVMContext());
4288 llvm::Value *Placeholder = llvm::PoisonValue::get(IRPtrTy);
4313 if (
type->isReferenceType()) {
4322 param->
hasAttr<NSConsumedAttr>() &&
type->isObjCRetainableType()) {
4323 llvm::Value *ptr =
Builder.CreateLoad(local);
4326 Builder.CreateStore(null, local);
4337 type->castAsRecordDecl()->isParamDestroyedInCallee() &&
4342 "cleanup for callee-destructed param not recorded");
4344 llvm::Instruction *isActive =
Builder.CreateUnreachable();
4350 return llvm::isa_and_nonnull<llvm::ConstantPointerNull>(addr);
4360 const LValue &srcLV = writeback.
Source;
4361 Address srcAddr = srcLV.getAddress();
4363 "shouldn't have writeback for provably null argument");
4371 llvm::BasicBlock *contBB =
nullptr;
4377 if (!provablyNonNull) {
4382 CGF.
Builder.CreateCondBr(isNull, contBB, writebackBB);
4391 "icr.writeback-cast");
4400 if (writeback.
ToUse) {
4425 if (!provablyNonNull)
4434 for (
const auto &I : llvm::reverse(Cleanups)) {
4436 I.IsActiveIP->eraseFromParent();
4442 if (uop->getOpcode() == UO_AddrOf)
4443 return uop->getSubExpr();
4468 Address srcAddr = srcLV.getAddress();
4473 llvm::PointerType *destType =
4475 llvm::Type *destElemType =
4502 llvm::BasicBlock *contBB =
nullptr;
4503 llvm::BasicBlock *originBB =
nullptr;
4506 llvm::Value *finalArgument;
4510 if (provablyNonNull) {
4515 finalArgument = CGF.
Builder.CreateSelect(
4516 isNull, llvm::ConstantPointerNull::get(destType),
4522 originBB = CGF.
Builder.GetInsertBlock();
4525 CGF.
Builder.CreateCondBr(isNull, contBB, copyBB);
4527 condEval.
begin(CGF);
4531 llvm::Value *valueToUse =
nullptr;
4539 src = CGF.
Builder.CreateBitCast(src, destElemType,
"icr.cast");
4556 if (shouldCopy && !provablyNonNull) {
4557 llvm::BasicBlock *copyBB = CGF.
Builder.GetInsertBlock();
4562 llvm::PHINode *phiToUse =
4563 CGF.
Builder.CreatePHI(valueToUse->getType(), 2,
"icr.to-use");
4564 phiToUse->addIncoming(valueToUse, copyBB);
4565 phiToUse->addIncoming(llvm::PoisonValue::get(valueToUse->getType()),
4567 valueToUse = phiToUse;
4581 StackBase = CGF.
Builder.CreateStackSave(
"inalloca.save");
4587 CGF.
Builder.CreateStackRestore(StackBase);
4594 if (!AC.
getDecl() || !(
SanOpts.has(SanitizerKind::NonnullAttribute) ||
4595 SanOpts.has(SanitizerKind::NullabilityArg)))
4600 unsigned ArgNo = PVD ? PVD->getFunctionScopeIndex() : ParmNum;
4603 const NonNullAttr *NNAttr =
nullptr;
4604 if (
SanOpts.has(SanitizerKind::NonnullAttribute))
4607 bool CanCheckNullability =
false;
4608 if (
SanOpts.has(SanitizerKind::NullabilityArg) && !NNAttr && PVD &&
4609 !PVD->getType()->isRecordType()) {
4610 auto Nullability = PVD->getType()->getNullability();
4611 CanCheckNullability = Nullability &&
4613 PVD->getTypeSourceInfo();
4616 if (!NNAttr && !CanCheckNullability)
4623 AttrLoc = NNAttr->getLocation();
4624 CheckKind = SanitizerKind::SO_NonnullAttribute;
4625 Handler = SanitizerHandler::NonnullArg;
4627 AttrLoc = PVD->getTypeSourceInfo()->getTypeLoc().findNullabilityLoc();
4628 CheckKind = SanitizerKind::SO_NullabilityArg;
4629 Handler = SanitizerHandler::NullabilityArg;
4634 llvm::Constant *StaticData[] = {
4637 llvm::ConstantInt::get(
Int32Ty, ArgNo + 1),
4639 EmitCheck(std::make_pair(
Cond, CheckKind), Handler, StaticData, {});
4645 if (!AC.
getDecl() || !(
SanOpts.has(SanitizerKind::NonnullAttribute) ||
4646 SanOpts.has(SanitizerKind::NullabilityArg)))
4665 return llvm::any_of(ArgTypes, [&](
QualType Ty) {
4676 return classDecl->getTypeParamListAsWritten();
4680 return catDecl->getTypeParamList();
4690 llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
4694 assert((ParamsToSkip == 0 ||
Prototype.P) &&
4695 "Can't skip parameters if type info is not provided");
4705 bool IsVariadic =
false;
4707 const auto *MD = dyn_cast<const ObjCMethodDecl *>(
Prototype.P);
4709 IsVariadic = MD->isVariadic();
4711 MD,
CGM.getTarget().getTriple().isOSWindows());
4712 ArgTypes.assign(MD->param_type_begin() + ParamsToSkip,
4713 MD->param_type_end());
4716 IsVariadic = FPT->isVariadic();
4717 ExplicitCC = FPT->getExtInfo().getCC();
4718 ArgTypes.assign(FPT->param_type_begin() + ParamsToSkip,
4719 FPT->param_type_end());
4727 assert(Arg != ArgRange.end() &&
"Running over edge of argument list!");
4734 getContext().getCanonicalType((*Arg)->getType()).getTypePtr()) &&
4735 "type mismatch in call argument!");
4741 assert((Arg == ArgRange.end() || IsVariadic) &&
4742 "Extra arguments in non-variadic function!");
4747 for (
auto *A : llvm::drop_begin(ArgRange, ArgTypes.size()))
4748 ArgTypes.push_back(IsVariadic ? getVarArgType(A) : A->getType());
4749 assert((
int)ArgTypes.size() == (ArgRange.end() - ArgRange.begin()));
4757 CGM.getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()
4761 auto MaybeEmitImplicitObjectSize = [&](
unsigned I,
const Expr *Arg,
4770 auto SizeTy = Context.getSizeType();
4772 assert(EmittedArg.getScalarVal() &&
"We emitted nothing for the arg?");
4773 llvm::Value *
V = evaluateOrEmitBuiltinObjectSize(
4774 Arg, PS->getType(),
T, EmittedArg.getScalarVal(), PS->isDynamic());
4779 std::swap(Args.back(), *(&Args.back() - 1));
4784 assert(
getTarget().getTriple().getArch() == llvm::Triple::x86 &&
4785 "inalloca only supported on x86");
4790 size_t CallArgsStart = Args.size();
4791 for (
unsigned I = 0, E = ArgTypes.size(); I != E; ++I) {
4792 unsigned Idx = LeftToRight ? I : E - I - 1;
4794 unsigned InitialArgSize = Args.size();
4798 getContext().hasSameUnqualifiedType((*Arg)->getType(),
4802 "Argument and parameter types don't match");
4806 assert(InitialArgSize + 1 == Args.size() &&
4807 "The code below depends on only adding one arg per EmitCallArg");
4808 (void)InitialArgSize;
4811 if (!Args.back().hasLValue()) {
4812 RValue RVArg = Args.back().getKnownRValue();
4814 ParamsToSkip + Idx);
4818 MaybeEmitImplicitObjectSize(Idx, *Arg, RVArg);
4825 std::reverse(Args.begin() + CallArgsStart, Args.end());
4834struct DestroyUnpassedArg final : EHScopeStack::Cleanup {
4867 if (!HasLV &&
RV.isScalar())
4869 else if (!HasLV &&
RV.isComplex())
4872 auto Addr = HasLV ?
LV.getAddress() :
RV.getAggregateAddress();
4876 HasLV ?
LV.isVolatileQualified()
4877 :
RV.isVolatileQualified());
4889 std::optional<DisableDebugLocationUpdates> Dis;
4893 dyn_cast<ObjCIndirectCopyRestoreExpr>(E)) {
4907 "reference binding to unmaterialized r-value!");
4919 if (
type->isRecordType() &&
4920 type->castAsRecordDecl()->isParamDestroyedInCallee()) {
4927 bool DestroyedInCallee =
true, NeedsCleanup =
true;
4928 if (
const auto *RD =
type->getAsCXXRecordDecl())
4929 DestroyedInCallee = RD->hasNonTrivialDestructor();
4931 NeedsCleanup =
type.isDestructedType();
4933 if (DestroyedInCallee)
4940 if (DestroyedInCallee && NeedsCleanup) {
4947 llvm::Instruction *IsActive =
4956 !
type->isArrayParameterType() && !
type.isNonTrivialToPrimitiveCopy()) {
4966QualType CodeGenFunction::getVarArgType(
const Expr *Arg) {
4970 if (!getTarget().getTriple().isOSWindows())
4974 getContext().getTypeSize(Arg->
getType()) <
4978 return getContext().getIntPtrType();
4986void CodeGenFunction::AddObjCARCExceptionMetadata(llvm::Instruction *Inst) {
4987 if (CGM.getCodeGenOpts().OptimizationLevel != 0 &&
4988 !CGM.getCodeGenOpts().ObjCAutoRefCountExceptions)
4989 Inst->setMetadata(
"clang.arc.no_objc_arc_exceptions",
4990 CGM.getNoObjCARCExceptionsMetadata());
4996 const llvm::Twine &name) {
4997 return EmitNounwindRuntimeCall(callee, ArrayRef<llvm::Value *>(), name);
5003 ArrayRef<Address> args,
5004 const llvm::Twine &name) {
5005 SmallVector<llvm::Value *, 3> values;
5006 for (
auto arg : args)
5007 values.push_back(
arg.emitRawPointer(*
this));
5008 return EmitNounwindRuntimeCall(callee, values, name);
5013 ArrayRef<llvm::Value *> args,
5014 const llvm::Twine &name) {
5015 llvm::CallInst *call = EmitRuntimeCall(callee, args, name);
5016 call->setDoesNotThrow();
5023 const llvm::Twine &name) {
5024 return EmitRuntimeCall(callee, {},
name);
5029SmallVector<llvm::OperandBundleDef, 1>
5038 if (
auto *CalleeFn = dyn_cast<llvm::Function>(Callee->stripPointerCasts())) {
5039 if (CalleeFn->isIntrinsic() && CalleeFn->doesNotThrow()) {
5040 auto IID = CalleeFn->getIntrinsicID();
5041 if (!llvm::IntrinsicInst::mayLowerToFunctionCall(IID))
5054 const llvm::Twine &name) {
5055 llvm::CallInst *call = Builder.CreateCall(
5056 callee, args, getBundlesForFunclet(callee.getCallee()), name);
5057 call->setCallingConv(getRuntimeCC());
5059 if (CGM.shouldEmitConvergenceTokens() && call->isConvergent())
5071 llvm::InvokeInst *invoke =
Builder.CreateInvoke(
5073 invoke->setDoesNotReturn();
5076 llvm::CallInst *call =
Builder.CreateCall(callee, args, BundleList);
5077 call->setDoesNotReturn();
5086 const Twine &name) {
5094 const Twine &name) {
5104 const Twine &Name) {
5109 llvm::CallBase *Inst;
5111 Inst =
Builder.CreateCall(Callee, Args, BundleList, Name);
5114 Inst =
Builder.CreateInvoke(Callee, ContBB, InvokeDest, Args, BundleList,
5121 if (
CGM.getLangOpts().ObjCAutoRefCount)
5122 AddObjCARCExceptionMetadata(Inst);
5127void CodeGenFunction::deferPlaceholderReplacement(llvm::Instruction *Old,
5129 DeferredReplacements.push_back(
5130 std::make_pair(llvm::WeakTrackingVH(Old),
New));
5137[[nodiscard]] llvm::AttributeList
5138maybeRaiseRetAlignmentAttribute(llvm::LLVMContext &Ctx,
5139 const llvm::AttributeList &Attrs,
5140 llvm::Align NewAlign) {
5141 llvm::Align CurAlign = Attrs.getRetAlignment().valueOrOne();
5142 if (CurAlign >= NewAlign)
5144 llvm::Attribute AlignAttr = llvm::Attribute::getWithAlignment(Ctx, NewAlign);
5145 return Attrs.removeRetAttribute(Ctx, llvm::Attribute::AttrKind::Alignment)
5146 .addRetAttribute(Ctx, AlignAttr);
5149template <
typename AlignedAttrTy>
class AbstractAssumeAlignedAttrEmitter {
5154 const AlignedAttrTy *AA =
nullptr;
5156 llvm::Value *Alignment =
nullptr;
5157 llvm::ConstantInt *OffsetCI =
nullptr;
5163 AA = FuncDecl->
getAttr<AlignedAttrTy>();
5168 [[nodiscard]] llvm::AttributeList
5169 TryEmitAsCallSiteAttribute(
const llvm::AttributeList &Attrs) {
5170 if (!AA || OffsetCI || CGF.
SanOpts.
has(SanitizerKind::Alignment))
5172 const auto *AlignmentCI = dyn_cast<llvm::ConstantInt>(Alignment);
5177 if (!AlignmentCI->getValue().isPowerOf2())
5179 llvm::AttributeList NewAttrs = maybeRaiseRetAlignmentAttribute(
5182 AlignmentCI->getLimitedValue(llvm::Value::MaximumAlignment)));
5190 void EmitAsAnAssumption(SourceLocation Loc, QualType RetTy, RValue &Ret) {
5194 AA->getLocation(), Alignment, OffsetCI);
5200class AssumeAlignedAttrEmitter final
5201 :
public AbstractAssumeAlignedAttrEmitter<AssumeAlignedAttr> {
5203 AssumeAlignedAttrEmitter(CodeGenFunction &CGF_,
const Decl *FuncDecl)
5204 : AbstractAssumeAlignedAttrEmitter(CGF_, FuncDecl) {
5209 if (Expr *Offset = AA->getOffset()) {
5211 if (OffsetCI->isNullValue())
5218class AllocAlignAttrEmitter final
5219 :
public AbstractAssumeAlignedAttrEmitter<AllocAlignAttr> {
5221 AllocAlignAttrEmitter(CodeGenFunction &CGF_,
const Decl *FuncDecl,
5222 const CallArgList &CallArgs)
5223 : AbstractAssumeAlignedAttrEmitter(CGF_, FuncDecl) {
5227 Alignment = CallArgs[AA->getParamIndex().getLLVMIndex()]
5236 if (
auto *VT = dyn_cast<llvm::VectorType>(Ty))
5237 return VT->getPrimitiveSizeInBits().getKnownMinValue();
5238 if (
auto *AT = dyn_cast<llvm::ArrayType>(Ty))
5241 unsigned MaxVectorWidth = 0;
5242 if (
auto *ST = dyn_cast<llvm::StructType>(Ty))
5243 for (
auto *I : ST->elements())
5245 return MaxVectorWidth;
5252 llvm::CallBase **callOrInvoke,
bool IsMustTail,
5254 bool IsVirtualFunctionPointerThunk) {
5257 assert(Callee.isOrdinary() || Callee.isVirtual());
5264 llvm::FunctionType *IRFuncTy =
getTypes().GetFunctionType(CallInfo);
5266 const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl().getDecl();
5267 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
5274 if ((TargetDecl->
hasAttr<AlwaysInlineAttr>() &&
5275 (TargetDecl->
hasAttr<TargetAttr>() ||
5279 TargetDecl->
hasAttr<TargetAttr>())))
5286 const FunctionDecl *CalleeDecl = dyn_cast_or_null<FunctionDecl>(TargetDecl);
5287 CGM.getTargetCodeGenInfo().checkFunctionCallABI(
CGM, Loc, CallerDecl,
5288 CalleeDecl, CallArgs, RetTy);
5295 if (llvm::StructType *ArgStruct = CallInfo.
getArgStruct()) {
5296 const llvm::DataLayout &DL =
CGM.getDataLayout();
5298 llvm::AllocaInst *AI;
5300 IP = IP->getNextNode();
5301 AI =
new llvm::AllocaInst(ArgStruct, DL.getAllocaAddrSpace(),
"argmem",
5307 AI->setAlignment(Align.getAsAlign());
5308 AI->setUsedWithInAlloca(
true);
5309 assert(AI->isUsedWithInAlloca() && !AI->isStaticAlloca());
5310 ArgMemory =
RawAddress(AI, ArgStruct, Align);
5313 ClangToLLVMArgMapping IRFunctionArgs(
CGM.getContext(), CallInfo);
5319 bool NeedSRetLifetimeEnd =
false;
5325 if ((IsVirtualFunctionPointerThunk || IsMustTail) && RetAI.
isIndirect()) {
5327 IRFunctionArgs.getSRetArgNo(),
5336 if (IRFunctionArgs.hasSRetArg()) {
5351 IRCallArgs[IRFunctionArgs.getSRetArgNo()] =
5369 assert(CallInfo.
arg_size() == CallArgs.size() &&
5370 "Mismatch between function signature & arguments.");
5373 for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end();
5374 I != E; ++I, ++info_it, ++ArgNo) {
5378 if (IRFunctionArgs.hasPaddingArg(ArgNo))
5379 IRCallArgs[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
5382 unsigned FirstIRArg, NumIRArgs;
5383 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
5385 bool ArgHasMaybeUndefAttr =
5390 assert(NumIRArgs == 0);
5391 assert(
getTarget().getTriple().getArch() == llvm::Triple::x86);
5392 if (I->isAggregate()) {
5394 ? I->getKnownLValue().getAddress()
5395 : I->getKnownRValue().getAggregateAddress();
5396 llvm::Instruction *Placeholder =
5401 CGBuilderTy::InsertPoint IP =
Builder.saveIP();
5402 Builder.SetInsertPoint(Placeholder);
5415 deferPlaceholderReplacement(Placeholder,
Addr.getPointer());
5420 I->Ty,
getContext().getTypeAlignInChars(I->Ty),
5421 "indirect-arg-temp");
5422 I->copyInto(*
this,
Addr);
5431 I->copyInto(*
this,
Addr);
5438 assert(NumIRArgs == 1);
5439 if (I->isAggregate()) {
5449 ? I->getKnownLValue().getAddress()
5450 : I->getKnownRValue().getAggregateAddress();
5452 const llvm::DataLayout *TD = &
CGM.getDataLayout();
5454 assert((FirstIRArg >= IRFuncTy->getNumParams() ||
5455 IRFuncTy->getParamType(FirstIRArg)->getPointerAddressSpace() ==
5456 TD->getAllocaAddrSpace()) &&
5457 "indirect argument must be in alloca address space");
5459 bool NeedCopy =
false;
5460 if (
Addr.getAlignment() < Align &&
5461 llvm::getOrEnforceKnownAlignment(
Addr.emitRawPointer(*
this),
5465 }
else if (I->hasLValue()) {
5466 auto LV = I->getKnownLValue();
5471 if (!isByValOrRef ||
5472 (LV.getAlignment() <
getContext().getTypeAlignInChars(I->Ty))) {
5476 if (isByValOrRef &&
Addr.getType()->getAddressSpace() !=
5485 auto *
T = llvm::PointerType::get(
CGM.getLLVMContext(),
5493 *
this,
V, I->Ty.getAddressSpace(),
T,
true);
5494 if (ArgHasMaybeUndefAttr)
5495 Val =
Builder.CreateFreeze(Val);
5496 IRCallArgs[FirstIRArg] = Val;
5499 }
else if (I->getType()->isArrayParameterType()) {
5505 IRCallArgs[FirstIRArg] = I->getKnownRValue().getScalarVal();
5514 if (ArgHasMaybeUndefAttr)
5515 Val =
Builder.CreateFreeze(Val);
5516 IRCallArgs[FirstIRArg] = Val;
5521 CallLifetimeEndAfterCall.emplace_back(AI);
5524 I->copyInto(*
this, AI);
5529 assert(NumIRArgs == 0);
5537 assert(NumIRArgs == 1);
5539 if (!I->isAggregate())
5540 V = I->getKnownRValue().getScalarVal();
5543 I->hasLValue() ? I->getKnownLValue().getAddress()
5544 : I->getKnownRValue().getAggregateAddress());
5550 assert(!swiftErrorTemp.
isValid() &&
"multiple swifterror args");
5554 V, pointeeTy,
getContext().getTypeAlignInChars(pointeeTy));
5561 llvm::Value *errorValue =
Builder.CreateLoad(swiftErrorArg);
5562 Builder.CreateStore(errorValue, swiftErrorTemp);
5567 V->getType()->isIntegerTy())
5574 if (FirstIRArg < IRFuncTy->getNumParams() &&
5575 V->getType() != IRFuncTy->getParamType(FirstIRArg)) {
5576 assert(
V->getType()->isPointerTy() &&
"Only pointers can mismatch!");
5577 auto ActualAS = I->Ty.getAddressSpace();
5579 *
this,
V, ActualAS, IRFuncTy->getParamType(FirstIRArg));
5582 if (ArgHasMaybeUndefAttr)
5584 IRCallArgs[FirstIRArg] =
V;
5588 llvm::StructType *STy =
5593 if (!I->isAggregate()) {
5595 I->copyInto(*
this, Src);
5597 Src = I->hasLValue() ? I->getKnownLValue().getAddress()
5598 : I->getKnownRValue().getAggregateAddress();
5608 llvm::TypeSize SrcTypeSize =
5609 CGM.getDataLayout().getTypeAllocSize(SrcTy);
5610 llvm::TypeSize DstTypeSize =
CGM.getDataLayout().getTypeAllocSize(STy);
5611 if (SrcTypeSize.isScalable()) {
5612 assert(STy->containsHomogeneousScalableVectorTypes() &&
5613 "ABI only supports structure with homogeneous scalable vector "
5615 assert(SrcTypeSize == DstTypeSize &&
5616 "Only allow non-fractional movement of structure with "
5617 "homogeneous scalable vector type");
5618 assert(NumIRArgs == STy->getNumElements());
5620 llvm::Value *StoredStructValue =
5622 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
5623 llvm::Value *Extract =
Builder.CreateExtractValue(
5624 StoredStructValue, i, Src.
getName() +
".extract" + Twine(i));
5625 IRCallArgs[FirstIRArg + i] = Extract;
5628 uint64_t SrcSize = SrcTypeSize.getFixedValue();
5629 uint64_t DstSize = DstTypeSize.getFixedValue();
5635 if (SrcSize < DstSize) {
5638 Builder.CreateMemCpy(TempAlloca, Src, SrcSize);
5644 assert(NumIRArgs == STy->getNumElements());
5645 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
5647 llvm::Value *LI =
Builder.CreateLoad(EltPtr);
5648 if (ArgHasMaybeUndefAttr)
5649 LI =
Builder.CreateFreeze(LI);
5650 IRCallArgs[FirstIRArg + i] = LI;
5655 assert(NumIRArgs == 1);
5663 auto *ATy = dyn_cast<llvm::ArrayType>(Load->getType());
5668 if (ArgHasMaybeUndefAttr)
5669 Load =
Builder.CreateFreeze(Load);
5670 IRCallArgs[FirstIRArg] = Load;
5678 auto layout =
CGM.getDataLayout().getStructLayout(coercionType);
5680 auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
5684 bool NeedLifetimeEnd =
false;
5685 if (I->isAggregate()) {
5686 addr = I->hasLValue() ? I->getKnownLValue().getAddress()
5687 : I->getKnownRValue().getAggregateAddress();
5690 RValue RV = I->getKnownRValue();
5694 auto scalarAlign =
CGM.getDataLayout().getPrefTypeAlign(scalarType);
5699 layout->getAlignment(), scalarAlign)),
5701 nullptr, &AllocaAddr);
5709 unsigned IRArgPos = FirstIRArg;
5710 unsigned unpaddedIndex = 0;
5711 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
5712 llvm::Type *eltType = coercionType->getElementType(i);
5719 : unpaddedCoercionType,
5721 if (ArgHasMaybeUndefAttr)
5722 elt =
Builder.CreateFreeze(elt);
5723 IRCallArgs[IRArgPos++] = elt;
5725 assert(IRArgPos == FirstIRArg + NumIRArgs);
5727 if (NeedLifetimeEnd)
5733 unsigned IRArgPos = FirstIRArg;
5734 ExpandTypeToArgs(I->Ty, *I, IRFuncTy, IRCallArgs, IRArgPos);
5735 assert(IRArgPos == FirstIRArg + NumIRArgs);
5741 if (!I->isAggregate()) {
5743 I->copyInto(*
this, Src);
5745 Src = I->hasLValue() ? I->getKnownLValue().getAddress()
5746 : I->getKnownRValue().getAggregateAddress();
5752 CGM.getABIInfo().createCoercedLoad(Src, ArgInfo, *
this);
5753 IRCallArgs[FirstIRArg] = Load;
5759 const CGCallee &ConcreteCallee = Callee.prepareConcreteCallee(*
this);
5765 assert(IRFunctionArgs.hasInallocaArg());
5766 IRCallArgs[IRFunctionArgs.getInallocaArgNo()] = Arg;
5777 auto simplifyVariadicCallee = [](llvm::FunctionType *CalleeFT,
5778 llvm::Value *Ptr) -> llvm::Function * {
5779 if (!CalleeFT->isVarArg())
5783 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Ptr)) {
5784 if (CE->getOpcode() == llvm::Instruction::BitCast)
5785 Ptr = CE->getOperand(0);
5788 llvm::Function *OrigFn = dyn_cast<llvm::Function>(Ptr);
5792 llvm::FunctionType *OrigFT = OrigFn->getFunctionType();
5796 if (OrigFT->isVarArg() ||
5797 OrigFT->getNumParams() != CalleeFT->getNumParams() ||
5798 OrigFT->getReturnType() != CalleeFT->getReturnType())
5801 for (
unsigned i = 0, e = OrigFT->getNumParams(); i != e; ++i)
5802 if (OrigFT->getParamType(i) != CalleeFT->getParamType(i))
5808 if (llvm::Function *OrigFn = simplifyVariadicCallee(IRFuncTy, CalleePtr)) {
5810 IRFuncTy = OrigFn->getFunctionType();
5821 for (
unsigned i = 0; i < IRCallArgs.size(); ++i)
5822 LargestVectorWidth = std::max(LargestVectorWidth,
5827 llvm::AttributeList Attrs;
5828 CGM.ConstructAttributeList(CalleePtr->getName(), CallInfo,
5833 if (
CallingConv == llvm::CallingConv::X86_VectorCall &&
5834 getTarget().getTriple().isWindowsArm64EC()) {
5835 CGM.Error(Loc,
"__vectorcall calling convention is not currently "
5840 if (FD->hasAttr<StrictFPAttr>())
5842 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::StrictFP);
5847 if (FD->hasAttr<OptimizeNoneAttr>() &&
getLangOpts().FastMath)
5848 CGM.AdjustMemoryAttribute(CalleePtr->getName(), Callee.getAbstractInfo(),
5853 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::NoMerge);
5857 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::NoInline);
5862 !
CGM.getTargetCodeGenInfo().wouldInliningViolateFunctionCallABI(
5863 CallerDecl, CalleeDecl))
5865 Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::AlwaysInline);
5870 Attrs.removeFnAttribute(
getLLVMContext(), llvm::Attribute::Convergent);
5879 !(TargetDecl && TargetDecl->
hasAttr<NoInlineAttr>()) &&
5880 !
CGM.getTargetCodeGenInfo().wouldInliningViolateFunctionCallABI(
5881 CallerDecl, CalleeDecl)) {
5883 Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::AlwaysInline);
5888 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::NoInline);
5895 CannotThrow =
false;
5904 CannotThrow = Attrs.hasFnAttr(llvm::Attribute::NoUnwind);
5906 if (
auto *FPtr = dyn_cast<llvm::Function>(CalleePtr))
5907 if (FPtr->hasFnAttribute(llvm::Attribute::NoUnwind))
5915 if (NeedSRetLifetimeEnd)
5923 if (
SanOpts.has(SanitizerKind::KCFI) &&
5924 !isa_and_nonnull<FunctionDecl>(TargetDecl))
5931 if (FD->hasAttr<StrictFPAttr>())
5933 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::StrictFP);
5935 AssumeAlignedAttrEmitter AssumeAlignedAttrEmitter(*
this, TargetDecl);
5936 Attrs = AssumeAlignedAttrEmitter.TryEmitAsCallSiteAttribute(Attrs);
5938 AllocAlignAttrEmitter AllocAlignAttrEmitter(*
this, TargetDecl, CallArgs);
5939 Attrs = AllocAlignAttrEmitter.TryEmitAsCallSiteAttribute(Attrs);
5944 CI =
Builder.CreateCall(IRFuncTy, CalleePtr, IRCallArgs, BundleList);
5947 CI =
Builder.CreateInvoke(IRFuncTy, CalleePtr, Cont, InvokeDest, IRCallArgs,
5951 if (CI->getCalledFunction() && CI->getCalledFunction()->hasName() &&
5952 CI->getCalledFunction()->getName().starts_with(
"_Z4sqrt")) {
5957 if (
CGM.getCodeGenOpts().CallGraphSection) {
5961 else if (
const auto *FPT =
5962 Callee.getAbstractInfo().getCalleeFunctionProtoType())
5966 "Cannot find the callee type to generate callee_type metadata.");
5970 CGM.createCalleeTypeMetadataForIcall(CST, *callOrInvoke);
5977 if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(
CurFuncDecl)) {
5978 if (
const auto *A = FD->getAttr<CFGuardAttr>()) {
5979 if (A->getGuard() == CFGuardAttr::GuardArg::nocf &&
5980 !CI->getCalledFunction())
5986 CI->setAttributes(Attrs);
5987 CI->setCallingConv(
static_cast<llvm::CallingConv::ID
>(
CallingConv));
5991 if (!CI->getType()->isVoidTy())
5992 CI->setName(
"call");
5994 if (
CGM.shouldEmitConvergenceTokens() && CI->isConvergent())
5995 CI = addConvergenceControlToken(CI);
5998 LargestVectorWidth =
6004 if (!CI->getCalledFunction())
6005 PGO->valueProfile(
Builder, llvm::IPVK_IndirectCallTarget, CI, CalleePtr);
6009 if (
CGM.getLangOpts().ObjCAutoRefCount)
6010 AddObjCARCExceptionMetadata(CI);
6013 if (llvm::CallInst *
Call = dyn_cast<llvm::CallInst>(CI)) {
6014 if (TargetDecl && TargetDecl->
hasAttr<NotTailCalledAttr>())
6015 Call->setTailCallKind(llvm::CallInst::TCK_NoTail);
6016 else if (IsMustTail) {
6019 CGM.getDiags().Report(Loc, diag::err_aix_musttail_unsupported);
6022 CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail) << 0;
6023 else if (
Call->isIndirectCall())
6024 CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail) << 1;
6025 else if (isa_and_nonnull<FunctionDecl>(TargetDecl)) {
6030 CGM.addUndefinedGlobalForTailCall(
6033 llvm::GlobalValue::LinkageTypes
Linkage =
CGM.getFunctionLinkage(
6035 if (llvm::GlobalValue::isWeakForLinker(
Linkage) ||
6036 llvm::GlobalValue::isDiscardableIfUnused(
Linkage))
6037 CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail)
6043 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
6052 if (TargetDecl && TargetDecl->
hasAttr<ErrorAttr>()) {
6053 llvm::ConstantInt *
Line =
6055 llvm::ConstantAsMetadata *MD = llvm::ConstantAsMetadata::get(
Line);
6057 CI->setMetadata(
"srcloc", MDT);
6065 if (CI->doesNotReturn()) {
6066 if (NeedSRetLifetimeEnd)
6070 if (
SanOpts.has(SanitizerKind::Unreachable)) {
6073 if (
auto *F = CI->getCalledFunction())
6074 F->removeFnAttr(llvm::Attribute::NoReturn);
6075 CI->removeFnAttr(llvm::Attribute::NoReturn);
6079 if (
SanOpts.hasOneOf(SanitizerKind::Address |
6080 SanitizerKind::KernelAddress)) {
6082 llvm::IRBuilder<>::InsertPointGuard IPGuard(
Builder);
6084 auto *FnType = llvm::FunctionType::get(
CGM.VoidTy,
false);
6085 llvm::FunctionCallee Fn =
6086 CGM.CreateRuntimeFunction(FnType,
"__asan_handle_no_return");
6092 Builder.ClearInsertionPoint();
6111 if (Cleanup && Cleanup->isFakeUse()) {
6112 CGBuilderTy::InsertPointGuard IPG(
Builder);
6114 Cleanup->getCleanup()->Emit(*
this, EHScopeStack::Cleanup::Flags());
6115 }
else if (!(Cleanup &&
6116 Cleanup->getCleanup()->isRedundantBeforeReturn())) {
6117 CGM.ErrorUnsupported(
MustTailCall,
"tail call skipping over cleanups");
6120 if (CI->getType()->isVoidTy())
6124 Builder.ClearInsertionPoint();
6130 if (swiftErrorTemp.
isValid()) {
6131 llvm::Value *errorResult =
Builder.CreateLoad(swiftErrorTemp);
6132 Builder.CreateStore(errorResult, swiftErrorArg);
6149 if (IsVirtualFunctionPointerThunk) {
6162 unsigned unpaddedIndex = 0;
6163 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
6164 llvm::Type *eltType = coercionType->getElementType(i);
6168 llvm::Value *elt = CI;
6169 if (requiresExtract)
6170 elt =
Builder.CreateExtractValue(elt, unpaddedIndex++);
6172 assert(unpaddedIndex == 0);
6173 Builder.CreateStore(elt, eltAddr);
6181 if (NeedSRetLifetimeEnd)
6198 llvm::Value *Real =
Builder.CreateExtractValue(CI, 0);
6199 llvm::Value *Imag =
Builder.CreateExtractValue(CI, 1);
6207 llvm::Value *
V = CI;
6208 if (
V->getType() != RetIRTy)
6218 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(RetIRTy)) {
6219 llvm::Value *
V = CI;
6220 if (
auto *ScalableSrcTy =
6221 dyn_cast<llvm::ScalableVectorType>(
V->getType())) {
6222 if (FixedDstTy->getElementType() ==
6223 ScalableSrcTy->getElementType()) {
6224 V =
Builder.CreateExtractVector(FixedDstTy,
V, uint64_t(0),
6234 getContext().getTypeInfoDataSizeInChars(RetTy).Width.getQuantity();
6238 DestIsVolatile =
false;
6239 DestSize =
getContext().getTypeSizeInChars(RetTy).getQuantity();
6263 DestIsVolatile =
false;
6265 CGM.getABIInfo().createCoercedStore(CI, StorePtr, RetAI, DestIsVolatile,
6272 llvm_unreachable(
"Invalid ABI kind for return argument");
6275 llvm_unreachable(
"Unhandled ABIArgInfo::Kind");
6280 if (Ret.isScalar() && TargetDecl) {
6281 AssumeAlignedAttrEmitter.EmitAsAnAssumption(Loc, RetTy, Ret);
6282 AllocAlignAttrEmitter.EmitAsAnAssumption(Loc, RetTy, Ret);
6288 LifetimeEnd.Emit(*
this, {});
6300 if (CalleeDecl && !CalleeDecl->
hasAttr<NoDebugAttr>() &&
6301 DI->getCallSiteRelatedAttrs() != llvm::DINode::FlagZero) {
6302 CodeGenFunction CalleeCGF(
CGM);
6304 Callee.getAbstractInfo().getCalleeDecl();
6305 CalleeCGF.
CurGD = CalleeGlobalDecl;
6308 DI->EmitFuncDeclForCallSite(
6309 CI, DI->getFunctionType(CalleeDecl, ResTy, Args), CalleeGlobalDecl);
6336 if (
VE->isMicrosoftABI())
6337 return CGM.getABIInfo().EmitMSVAArg(*
this, VAListAddr, Ty, Slot);
6338 return CGM.getABIInfo().EmitVAArg(*
this, VAListAddr, Ty, Slot);
6343 CGF.disableDebugInfo();
6347 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
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
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
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
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.
QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args)
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.
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
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)
bool isNull() const
Return true if this QualType doesn't point to a type yet.
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.