38#include "llvm/ABI/FunctionInfo.h"
39#include "llvm/ABI/IRTypeMapper.h"
40#include "llvm/ABI/TargetInfo.h"
41#include "llvm/ABI/Types.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringExtras.h"
44#include "llvm/Analysis/ValueTracking.h"
45#include "llvm/IR/Assumptions.h"
46#include "llvm/IR/AttributeMask.h"
47#include "llvm/IR/Attributes.h"
48#include "llvm/IR/CallingConv.h"
49#include "llvm/IR/DataLayout.h"
50#include "llvm/IR/DebugInfoMetadata.h"
51#include "llvm/IR/InlineAsm.h"
52#include "llvm/IR/IntrinsicInst.h"
53#include "llvm/IR/Intrinsics.h"
54#include "llvm/IR/Type.h"
55#include "llvm/Transforms/Utils/Local.h"
68 if (Target.getTriple().isSPIROrSPIRV())
69 return llvm::CallingConv::SPIR_FUNC;
70 return llvm::CallingConv::C;
72 return llvm::CallingConv::X86_StdCall;
74 return llvm::CallingConv::X86_FastCall;
76 return llvm::CallingConv::X86_RegCall;
78 return llvm::CallingConv::X86_ThisCall;
80 return llvm::CallingConv::Win64;
82 return llvm::CallingConv::X86_64_SysV;
84 return llvm::CallingConv::ARM_AAPCS;
86 return llvm::CallingConv::ARM_AAPCS_VFP;
88 return llvm::CallingConv::Intel_OCL_BI;
91 return llvm::CallingConv::C;
94 return llvm::CallingConv::X86_VectorCall;
96 return llvm::CallingConv::AArch64_VectorCall;
98 return llvm::CallingConv::AArch64_SVE_VectorCall;
100 return CGM.getTargetCodeGenInfo().getDeviceKernelCallingConv();
102 return llvm::CallingConv::PreserveMost;
104 return llvm::CallingConv::PreserveAll;
106 return llvm::CallingConv::Swift;
108 return llvm::CallingConv::SwiftTail;
110 return llvm::CallingConv::M68k_RTD;
112 return llvm::CallingConv::PreserveNone;
116#define CC_VLS_CASE(ABI_VLEN) \
117 case CC_RISCVVLSCall_##ABI_VLEN: \
118 return llvm::CallingConv::RISCV_VLSCall_##ABI_VLEN;
133 llvm_unreachable(
"unhandled calling convention");
144 RecTy = Context.getCanonicalTagType(RD);
146 RecTy = Context.VoidTy;
151 return Context.getPointerType(RecTy);
177 assert(paramInfos.size() <= prefixArgs);
178 assert(proto->
getNumParams() + prefixArgs <= totalArgs);
180 paramInfos.reserve(totalArgs);
183 paramInfos.resize(prefixArgs);
187 paramInfos.push_back(ParamInfo);
189 if (ParamInfo.hasPassObjectSize())
190 paramInfos.emplace_back();
193 assert(paramInfos.size() <= totalArgs &&
194 "Did we forget to insert pass_object_size args?");
196 paramInfos.resize(totalArgs);
206 if (!FPT->hasExtParameterInfos()) {
207 assert(paramInfos.empty() &&
208 "We have paramInfos, but the prototype doesn't?");
209 prefix.append(FPT->param_type_begin(), FPT->param_type_end());
213 unsigned PrefixSize = prefix.size();
217 prefix.reserve(prefix.size() + FPT->getNumParams());
219 auto ExtInfos = FPT->getExtParameterInfos();
220 assert(ExtInfos.size() == FPT->getNumParams());
221 for (
unsigned I = 0, E = FPT->getNumParams(); I != E; ++I) {
222 prefix.push_back(FPT->getParamType(I));
223 if (ExtInfos[I].hasPassObjectSize())
248 FTP->getExtInfo(), paramInfos,
Required,
259 return ::arrangeLLVMFunctionInfo(*
this,
false, argTypes,
264 bool IsTargetDefaultMSABI) {
269 if (D->
hasAttr<FastCallAttr>())
275 if (D->
hasAttr<ThisCallAttr>())
278 if (D->
hasAttr<VectorCallAttr>())
284 if (PcsAttr *PCS = D->
getAttr<PcsAttr>())
287 if (D->
hasAttr<AArch64VectorPcsAttr>())
290 if (D->
hasAttr<AArch64SVEPcsAttr>())
293 if (D->
hasAttr<DeviceKernelAttr>())
296 if (D->
hasAttr<IntelOclBiccAttr>())
305 if (D->
hasAttr<PreserveMostAttr>())
308 if (D->
hasAttr<PreserveAllAttr>())
314 if (D->
hasAttr<PreserveNoneAttr>())
317 if (D->
hasAttr<RISCVVectorCCAttr>())
320 if (RISCVVLSCCAttr *PCS = D->
getAttr<RISCVVLSCCAttr>()) {
321 switch (PCS->getVectorWidth()) {
323 llvm_unreachable(
"Invalid RISC-V VLS ABI VLEN");
324#define CC_VLS_CASE(ABI_VLEN) \
326 return CC_RISCVVLSCall_##ABI_VLEN;
364 CanonicalFTP.getTypePtr(), argTypes.size());
367 CanonicalFTP->getReturnType().getUnqualifiedType(),
369 paramInfos, required, MD);
375 if (FD->
hasAttr<CUDAGlobalAttr>()) {
407 argTypes, prototype->getExtInfo(), paramInfos,
417 !Target.getCXXABI().hasConstructorVariants();
430 bool PassParams =
true;
432 if (
auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
435 if (
auto Inherited = CD->getInheritedConstructor())
447 if (!paramInfos.empty()) {
450 paramInfos.insert(paramInfos.begin() + 1, AddedArgs.
Prefix,
453 paramInfos.append(AddedArgs.
Suffix,
458 (PassParams && MD->isVariadic() ?
RequiredArgs(argTypes.size())
464 ? CGM.getContext().VoidPtrTy
467 argTypes, extInfo, paramInfos, required, MD);
473 for (
auto &arg : args)
481 for (
auto &arg : args)
488 unsigned totalArgs) {
506 unsigned ExtraPrefixArgs,
unsigned ExtraSuffixArgs,
509 for (
const auto &Arg : args)
510 ArgTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
513 unsigned TotalPrefixArgs = 1 + ExtraPrefixArgs;
518 FPT, TotalPrefixArgs + ExtraSuffixArgs)
524 ? CGM.getContext().VoidPtrTy
531 if (PassProtoArgs && FPT->hasExtParameterInfos()) {
538 ArgTypes, Info, ParamInfos,
Required,
548 if (MD->isImplicitObjectMemberFunction())
556 if (DeviceKernelAttr::isOpenCLSpelling(FD->
getAttr<DeviceKernelAttr>()) &&
559 CGM.getTargetCodeGenInfo().setOCLKernelStubCallingConvention(FT);
567 {}, noProto->getExtInfo(), {},
601 argTys.push_back(Context.getCanonicalParamType(receiverType));
603 argTys.push_back(Context.getCanonicalParamType(Context.getObjCSelType()));
605 argTys.push_back(Context.getCanonicalParamType(I->getType()));
607 I->hasAttr<NoEscapeAttr>());
608 extParamInfos.push_back(extParamInfo);
612 bool IsTargetDefaultMSABI =
618 if (
getContext().getLangOpts().ObjCAutoRefCount &&
619 MD->
hasAttr<NSReturnsRetainedAttr>())
657 assert(MD->
isVirtual() &&
"only methods have thunks");
674 ArgTys.push_back(*FTP->param_type_begin());
676 ArgTys.push_back(Context.IntTy);
677 CallingConv CC = Context.getDefaultCallingConvention(
689 unsigned numExtraRequiredArgs,
bool chainCall,
691 assert(args.size() >= numExtraRequiredArgs);
701 if (proto->isVariadic())
704 if (proto->hasExtParameterInfos())
718 for (
const auto &arg : args)
723 paramInfos, required, ABIInfoFD);
734 chainCall ? 1 : 0, chainCall, ABIInfoFD);
766 for (
const auto &Arg : args)
767 argTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
809 assert(numPrefixArgs + 1 <= args.size() &&
810 "Emitting a call with less args than the required prefix?");
821 paramInfos, required, ABIInfoFD);
833 assert(signature.
arg_size() <= args.size());
834 unsigned X86ABIAVXLevel =
835 CGM.getABIInfo().getX86ABIAVXLevel(ABIInfoFD, signature.
getExtInfo());
836 if (signature.
arg_size() == args.size() &&
842 if (!sigParamInfos.empty()) {
843 paramInfos.append(sigParamInfos.begin(), sigParamInfos.end());
844 paramInfos.resize(args.size());
882 return "IndirectAliased";
888 return "CoerceAndExpand";
890 return "TargetSpecific";
894 llvm_unreachable(
"Unknown kind");
900 MappedArgTypes.reserve(FI.
arg_size());
902 MappedArgTypes.push_back(AbiMapper->convertType(Arg.type));
905 llvm::abi::RequiredArgs AbiRequired = llvm::abi::RequiredArgs::All;
907 AbiRequired = llvm::abi::RequiredArgs(
Required.getNumRequiredArgs());
909 auto AbiFI = llvm::abi::FunctionInfo::create(
911 MappedArgTypes, AbiRequired);
920 auto ConvertABIArgInfo = [&](
ABIArgInfo &Target,
923 auto Check = [&](
bool Cond, llvm::function_ref<void()> MessageFn) {
927 llvm::dbgs() <<
"For return value of type ";
929 llvm::dbgs() <<
"For argument " << ArgNo <<
" of type ";
930 llvm::dbgs() <<
Type <<
": ";
932 llvm::dbgs() <<
"\n";
935 auto CheckSimple = [&](
auto TargetVal,
auto ResVal, StringRef What) {
936 Check(TargetVal == ResVal, [&]() {
937 llvm::dbgs() << What <<
" mismatch (expected: " << TargetVal
938 <<
", given: " << ResVal <<
")";
943 Check(Target.getKind() == Res.
getKind(), [&]() {
944 llvm::dbgs() <<
"Kind mismatch (expected: "
945 << abiKindToString(Target.getKind())
946 <<
", given: " << abiKindToString(Res.getKind()) <<
")";
951 llvm::Type *TargetType = Target.getCoerceToType();
958 Check(TargetType == ResType, [&]() {
959 llvm::dbgs() <<
"CoerceToType mismatch (expected: " << *TargetType
960 <<
", given: " << *ResType <<
")";
966 CheckSimple(Target.isSignExt(), Res.
isSignExt(),
"SignExt");
967 CheckSimple(Target.isZeroExt(), Res.
isZeroExt(),
"ZeroExt");
970 CheckSimple(Target.getDirectAlign(), Res.
getDirectAlign(),
"DirectAlign");
984 "IndirectAddrSpace");
988 llvm::dbgs() <<
"IndirectAlign mismatch (expected: "
989 << Target.getIndirectAlign().getQuantity()
990 <<
", given: " << Res.getIndirectAlign().getQuantity()
995 Check(Target.getUnpaddedCoerceAndExpandType() ==
998 llvm::dbgs() <<
"UnpaddedCoerceAndExpandType mismatch (expected: "
999 << *Target.getUnpaddedCoerceAndExpandType()
1001 << *Res.getUnpaddedCoerceAndExpandType() <<
")";
1011 auto ConvertABIArgInfo =
1016 ConvertABIArgInfo(FI.
getReturnInfo(), AbiFI->getReturnInfo(),
1020 for (
auto [CGArg, AbiArg] :
1021 llvm::zip_equal(FI.
arguments(), AbiFI->arguments()))
1022 ConvertABIArgInfo(CGArg.info, AbiArg.Info, CGArg.type, ArgNo++);
1025ABIArgInfo CodeGenModule::convertABIArgInfo(
const llvm::abi::ArgInfo &AbiInfo,
1027 switch (AbiInfo.getKind()) {
1028 case llvm::abi::ArgInfo::Direct: {
1029 llvm::Type *CoercedType =
nullptr;
1030 if (AbiInfo.getCoerceToType())
1031 CoercedType = AbiReverseMapper->convertType(AbiInfo.getCoerceToType());
1033 CoercedType = getTypes().ConvertType(
Type);
1034 unsigned DirectAlign = 0;
1035 if (llvm::MaybeAlign Align = AbiInfo.getDirectAlign())
1036 DirectAlign = Align->value();
1041 AbiInfo.getCanBeFlattened(), DirectAlign);
1043 case llvm::abi::ArgInfo::Extend: {
1044 llvm::Type *CoercedType =
nullptr;
1045 if (AbiInfo.getCoerceToType())
1046 CoercedType = AbiReverseMapper->convertType(AbiInfo.getCoerceToType());
1048 CoercedType = getTypes().ConvertType(
Type);
1054 if (AbiInfo.isSignExt())
1056 if (AbiInfo.isZeroExt())
1060 case llvm::abi::ArgInfo::Indirect: {
1064 AbiInfo.getIndirectByVal(),
1065 AbiInfo.getIndirectRealign());
1067 case llvm::abi::ArgInfo::IndirectAliased: {
1069 CharUnits Alignment =
1072 AbiInfo.getIndirectAddrSpace(),
1073 AbiInfo.getIndirectRealign());
1075 case llvm::abi::ArgInfo::Ignore:
1077 case llvm::abi::ArgInfo::CoerceAndExpand: {
1078 llvm::StructType *CoercedType = llvm::cast<llvm::StructType>(
1079 AbiReverseMapper->convertType(AbiInfo.getCoerceToType()));
1080 llvm::Type *UnpaddedType =
1081 AbiReverseMapper->convertType(AbiInfo.getUnpaddedCoerceAndExpandType());
1085 llvm_unreachable(
"Unexpected llvm::abi::ArgInfo kind");
1096 assert(llvm::all_of(argTypes,
1104 bool isDelegateCall =
1106 unsigned X86ABIAVXLevel = CGM.getABIInfo().getX86ABIAVXLevel(ABIInfoFD, info);
1110 paramInfos, required, resultType, argTypes);
1120 llvm::FoldingSetNodeID ID;
1122 X86ABIAVXLevel, info, paramInfos, required,
1123 resultType, argTypes);
1125 llvm::FoldingSetInsertToken InsertToken;
1130 unsigned CC = ClangCallConvToLLVMCallConv(info.getCC());
1134 X86ABIAVXLevel, info, paramInfos, resultType,
1135 argTypes, required);
1136 FunctionInfos.insert(FI, InsertToken);
1138 bool inserted = FunctionsBeingProcessed.insert(FI).second;
1140 assert(inserted &&
"Recursively being processed?");
1144 (CC == llvm::CallingConv::SPIR_KERNEL || CC == llvm::CallingConv::C)) {
1149 assert(CC != llvm::CallingConv::C || getContext().getLangOpts().
OpenCL);
1154 return CGM.getTriple().isSPIRV() &&
1155 Arg.type.getTypePtr()->isOpenCLSpecificType();
1157 if (CC == llvm::CallingConv::SPIR_KERNEL &&
1158 CGM.shouldUseLLVMABILowering(CC) &&
1159 llvm::none_of(FI->
arguments(), IsSPIRVOpenCLType))
1160 CGM.computeABIInfoUsingLib(*FI);
1165 }
else if (CGM.shouldUseLLVMABILowering(CC)) {
1166 CGM.computeABIInfoUsingLib(*FI);
1168 CGM.getABIInfo().computeInfo(*FI);
1179 if (I.info.canHaveCoerceToType() && I.info.getCoerceToType() ==
nullptr)
1180 I.info.setCoerceToType(ConvertType(I.type));
1182 bool erased = FunctionsBeingProcessed.erase(FI);
1184 assert(erased &&
"Not in set?");
1190 unsigned llvmCC,
bool instanceMethod,
bool chainCall,
bool delegateCall,
1194 assert(paramInfos.empty() || paramInfos.size() == argTypes.size());
1198 void *buffer =
operator new(totalSizeToAlloc<ArgInfo, ExtParameterInfo>(
1199 argTypes.size() + 1, paramInfos.size()));
1201 CGFunctionInfo *FI =
new (buffer) CGFunctionInfo();
1202 FI->CallingConvention = llvmCC;
1203 FI->EffectiveCallingConvention = llvmCC;
1204 FI->ASTCallingConvention = info.getCC();
1205 FI->InstanceMethod = instanceMethod;
1206 FI->ChainCall = chainCall;
1207 FI->DelegateCall = delegateCall;
1208 FI->CmseNSCall = info.getCmseNSCall();
1209 FI->NoReturn = info.getNoReturn();
1210 FI->ReturnsRetained = info.getProducesResult();
1211 FI->NoCallerSavedRegs = info.getNoCallerSavedRegs();
1212 FI->NoCfCheck = info.getNoCfCheck();
1213 FI->Required = required;
1214 FI->HasRegParm = info.getHasRegParm();
1215 FI->RegParm = info.getRegParm();
1216 FI->X86ABIAVXLevel = X86ABIAVXLevel;
1217 FI->ArgStruct =
nullptr;
1218 FI->ArgStructAlign = 0;
1219 FI->NumArgs = argTypes.size();
1220 FI->HasExtParameterInfos = !paramInfos.empty();
1221 FI->getArgsBuffer()[0].
type = resultType;
1222 FI->MaxVectorWidth = 0;
1223 for (
unsigned i = 0, e = argTypes.size(); i != e; ++i)
1224 FI->getArgsBuffer()[i + 1].
type = argTypes[i];
1225 for (
unsigned i = 0, e = paramInfos.size(); i != e; ++i)
1226 FI->getExtParameterInfosBuffer()[i] = paramInfos[i];
1236struct TypeExpansion {
1237 enum TypeExpansionKind {
1249 const TypeExpansionKind Kind;
1251 TypeExpansion(TypeExpansionKind K) : Kind(K) {}
1252 virtual ~TypeExpansion() {}
1255struct ConstantArrayExpansion : TypeExpansion {
1259 ConstantArrayExpansion(QualType EltTy, uint64_t NumElts)
1260 : TypeExpansion(TEK_ConstantArray), EltTy(EltTy), NumElts(NumElts) {}
1261 static bool classof(
const TypeExpansion *TE) {
1262 return TE->Kind == TEK_ConstantArray;
1266struct RecordExpansion : TypeExpansion {
1267 SmallVector<const CXXBaseSpecifier *, 1> Bases;
1269 SmallVector<const FieldDecl *, 1> Fields;
1271 RecordExpansion(SmallVector<const CXXBaseSpecifier *, 1> &&Bases,
1272 SmallVector<const FieldDecl *, 1> &&Fields)
1273 : TypeExpansion(TEK_Record), Bases(std::move(Bases)),
1274 Fields(std::move(Fields)) {}
1275 static bool classof(
const TypeExpansion *TE) {
1276 return TE->Kind == TEK_Record;
1280struct ComplexExpansion : TypeExpansion {
1283 ComplexExpansion(QualType EltTy) : TypeExpansion(
TEK_Complex), EltTy(EltTy) {}
1284 static bool classof(
const TypeExpansion *TE) {
1289struct NoExpansion : TypeExpansion {
1290 NoExpansion() : TypeExpansion(TEK_None) {}
1291 static bool classof(
const TypeExpansion *TE) {
return TE->Kind == TEK_None; }
1295static std::unique_ptr<TypeExpansion>
1298 return std::make_unique<ConstantArrayExpansion>(AT->getElementType(),
1304 assert(!RD->hasFlexibleArrayMember() &&
1305 "Cannot expand structure with flexible array.");
1306 if (RD->isUnion()) {
1312 for (
const auto *FD : RD->fields()) {
1313 if (FD->isZeroLengthBitField())
1315 assert(!FD->isBitField() &&
1316 "Cannot expand structure with bit-field members.");
1317 CharUnits FieldSize = Context.getTypeSizeInChars(FD->getType());
1318 if (UnionSize < FieldSize) {
1319 UnionSize = FieldSize;
1324 Fields.push_back(LargestFD);
1326 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
1327 assert(!CXXRD->isDynamicClass() &&
1328 "cannot expand vtable pointers in dynamic classes");
1329 llvm::append_range(Bases, llvm::make_pointer_range(CXXRD->bases()));
1332 for (
const auto *FD : RD->fields()) {
1333 if (FD->isZeroLengthBitField())
1335 assert(!FD->isBitField() &&
1336 "Cannot expand structure with bit-field members.");
1337 Fields.push_back(FD);
1340 return std::make_unique<RecordExpansion>(std::move(Bases),
1344 return std::make_unique<ComplexExpansion>(CT->getElementType());
1346 return std::make_unique<NoExpansion>();
1351 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1354 if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1356 for (
auto BS : RExp->Bases)
1358 for (
auto FD : RExp->Fields)
1371 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1372 for (
int i = 0, n = CAExp->NumElts; i < n; i++) {
1375 }
else if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1376 for (
auto BS : RExp->Bases)
1378 for (
auto FD : RExp->Fields)
1380 }
else if (
auto CExp = dyn_cast<ComplexExpansion>(Exp.get())) {
1391 ConstantArrayExpansion *CAE,
1393 llvm::function_ref<
void(
Address)> Fn) {
1394 for (
int i = 0, n = CAE->NumElts; i < n; i++) {
1400void CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV,
1401 llvm::Function::arg_iterator &AI) {
1402 assert(LV.isSimple() &&
1403 "Unexpected non-simple lvalue during struct expansion.");
1406 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1408 *
this, CAExp, LV.getAddress(), [&](Address EltAddr) {
1409 LValue LV = MakeAddrLValue(EltAddr, CAExp->EltTy);
1410 ExpandTypeFromArgs(CAExp->EltTy, LV, AI);
1412 }
else if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1414 for (
const CXXBaseSpecifier *BS : RExp->Bases) {
1418 false, SourceLocation());
1419 LValue SubLV = MakeAddrLValue(Base, BS->
getType());
1422 ExpandTypeFromArgs(BS->
getType(), SubLV, AI);
1424 for (
auto FD : RExp->Fields) {
1426 LValue SubLV = EmitLValueForFieldInitialization(LV, FD);
1427 ExpandTypeFromArgs(FD->getType(), SubLV, AI);
1430 auto realValue = &*AI++;
1431 auto imagValue = &*AI++;
1432 EmitStoreOfComplex(
ComplexPairTy(realValue, imagValue), LV,
true);
1437 llvm::Value *Arg = &*AI++;
1438 if (LV.isBitField()) {
1444 if (Arg->getType()->isPointerTy()) {
1446 Arg = Builder.CreateBitCast(Arg,
Addr.getElementType());
1448 EmitStoreOfScalar(Arg, LV);
1453void CodeGenFunction::ExpandTypeToArgs(
1454 QualType Ty, CallArg Arg, llvm::FunctionType *IRFuncTy,
1455 SmallVectorImpl<llvm::Value *> &IRCallArgs,
unsigned &IRCallArgPos) {
1457 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1462 CallArg(convertTempToRValue(EltAddr, CAExp->EltTy, SourceLocation()),
1464 ExpandTypeToArgs(CAExp->EltTy, EltArg, IRFuncTy, IRCallArgs,
1467 }
else if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1470 for (
const CXXBaseSpecifier *BS : RExp->Bases) {
1474 false, SourceLocation());
1478 ExpandTypeToArgs(BS->
getType(), BaseArg, IRFuncTy, IRCallArgs,
1482 LValue LV = MakeAddrLValue(This, Ty);
1483 for (
auto FD : RExp->Fields) {
1485 CallArg(EmitRValueForField(LV, FD, SourceLocation()), FD->getType());
1486 ExpandTypeToArgs(FD->getType(), FldArg, IRFuncTy, IRCallArgs,
1491 IRCallArgs[IRCallArgPos++] = CV.first;
1492 IRCallArgs[IRCallArgPos++] = CV.second;
1496 assert(RV.isScalar() &&
1497 "Unexpected non-scalar rvalue during struct expansion.");
1500 llvm::Value *
V = RV.getScalarVal();
1501 if (IRCallArgPos < IRFuncTy->getNumParams() &&
1502 V->getType() != IRFuncTy->getParamType(IRCallArgPos))
1503 V = Builder.CreateBitCast(
V, IRFuncTy->getParamType(IRCallArgPos));
1505 IRCallArgs[IRCallArgPos++] =
V;
1513 const Twine &Name =
"tmp") {
1526 llvm::StructType *SrcSTy,
1530 if (SrcSTy->getNumElements() == 0)
1539 uint64_t FirstEltSize = CGF.
CGM.
getDataLayout().getTypeStoreSize(FirstElt);
1540 if (FirstEltSize < DstSize &&
1549 if (llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy))
1564 if (Val->getType() == Ty)
1570 return CGF.
Builder.CreateBitCast(Val, Ty,
"coerce.val");
1576 llvm::Type *DestIntTy = Ty;
1580 if (Val->getType() != DestIntTy) {
1582 if (DL.isBigEndian()) {
1585 uint64_t SrcSize = DL.getTypeSizeInBits(Val->getType());
1586 uint64_t DstSize = DL.getTypeSizeInBits(DestIntTy);
1588 if (SrcSize > DstSize) {
1589 Val = CGF.
Builder.CreateLShr(Val, SrcSize - DstSize,
"coerce.highbits");
1590 Val = CGF.
Builder.CreateTrunc(Val, DestIntTy,
"coerce.val.ii");
1592 Val = CGF.
Builder.CreateZExt(Val, DestIntTy,
"coerce.val.ii");
1593 Val = CGF.
Builder.CreateShl(Val, DstSize - SrcSize,
"coerce.highbits");
1597 Val = CGF.
Builder.CreateIntCast(Val, DestIntTy,
false,
"coerce.val.ii");
1602 Val = CGF.
Builder.CreateIntToPtr(Val, Ty,
"coerce.val.ip");
1609 if (PFPFields.empty())
1612 auto LoadCoercedField = [&](
CharUnits Offset,
1613 llvm::Type *FieldType) -> llvm::Value * {
1618 if (!PFPFields.empty() && PFPFields[0].Offset == Offset) {
1622 FieldVal = CGF.
Builder.CreatePtrToInt(FieldVal, FieldType);
1623 PFPFields.erase(PFPFields.begin());
1640 Val = CGF.
Builder.CreatePtrToInt(Val, Ty);
1644 auto *ET = AT->getElementType();
1648 llvm::Value *Val = llvm::PoisonValue::get(AT);
1649 for (
unsigned Idx = 0; Idx != AT->getNumElements(); ++Idx, Offset += WordSize)
1650 Val = CGF.
Builder.CreateInsertValue(Val, LoadCoercedField(Offset, ET), Idx);
1674 if (llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy)) {
1676 DstSize.getFixedValue(), CGF);
1691 if (!SrcSize.isScalable() && !DstSize.isScalable() &&
1692 SrcSize.getFixedValue() >= DstSize.getFixedValue()) {
1706 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(Ty)) {
1707 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
1710 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
1711 FixedSrcTy->getElementType()->isIntegerTy(8)) {
1712 ScalableDstTy = llvm::ScalableVectorType::get(
1713 FixedSrcTy->getElementType(),
1715 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
1717 if (ScalableDstTy->getElementType() == FixedSrcTy->getElementType()) {
1719 auto *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
1721 ScalableDstTy, PoisonVec, Load, uint64_t(0),
"cast.scalable");
1723 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, Ty));
1724 if (
Result->getType() != ScalableDstTy)
1726 if (
Result->getType() != Ty)
1739 llvm::ConstantInt::get(CGF.
IntPtrTy, SrcSize.getKnownMinValue()));
1746 if (PFPFields.empty())
1749 llvm::Type *SrcTy = Src->getType();
1750 auto StoreCoercedField = [&](
CharUnits Offset, llvm::Value *FieldVal) {
1751 if (!PFPFields.empty() && PFPFields[0].Offset == Offset) {
1756 PFPFields.erase(PFPFields.begin());
1776 auto *ET = AT->getElementType();
1780 for (
unsigned i = 0; i != AT->getNumElements(); ++i, Offset += WordSize)
1781 StoreCoercedField(Offset, CGF.
Builder.CreateExtractValue(Src, i));
1787 Address Dst, llvm::TypeSize DstSize,
1788 bool DstIsVolatile) {
1792 llvm::Type *SrcTy = Src->getType();
1793 llvm::TypeSize SrcSize =
CGM.getDataLayout().getTypeAllocSize(SrcTy);
1799 if (llvm::StructType *DstSTy =
1801 assert(!SrcSize.isScalable());
1803 SrcSize.getFixedValue(), *
this);
1810 if (SrcSize.isScalable() || SrcSize <= DstSize) {
1811 if (SrcTy->isIntegerTy() && Dst.
getElementType()->isPointerTy() &&
1815 auto *I =
Builder.CreateStore(Src, Dst, DstIsVolatile);
1817 }
else if (llvm::StructType *STy =
1818 dyn_cast<llvm::StructType>(Src->getType())) {
1821 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1823 llvm::Value *Elt =
Builder.CreateExtractValue(Src, i);
1824 auto *I =
Builder.CreateStore(Elt, EltPtr, DstIsVolatile);
1832 }
else if (SrcTy->isIntegerTy()) {
1834 llvm::Type *DstIntTy =
Builder.getIntNTy(DstSize.getFixedValue() * 8);
1851 Builder.CreateStore(Src, Tmp);
1852 auto *I =
Builder.CreateMemCpy(
1862 if (
unsigned offset = info.getDirectOffset()) {
1871static std::pair<llvm::Value *, bool>
1873 llvm::ScalableVectorType *FromTy, llvm::Value *
V,
1874 StringRef Name =
"") {
1877 if (FromTy->getElementType()->isIntegerTy(1) &&
1878 ToTy->getElementType() == CGF.
Builder.getInt8Ty()) {
1879 if (!FromTy->getElementCount().isKnownMultipleOf(8)) {
1880 FromTy = llvm::ScalableVectorType::get(
1881 FromTy->getElementType(),
1882 llvm::alignTo<8>(FromTy->getElementCount().getKnownMinValue()));
1883 llvm::Value *ZeroVec = llvm::Constant::getNullValue(FromTy);
1884 V = CGF.
Builder.CreateInsertVector(FromTy, ZeroVec,
V, uint64_t(0));
1886 FromTy = llvm::ScalableVectorType::get(
1887 ToTy->getElementType(),
1888 FromTy->getElementCount().getKnownMinValue() / 8);
1889 V = CGF.
Builder.CreateBitCast(
V, FromTy);
1891 if (FromTy->getElementType() == ToTy->getElementType()) {
1892 V->setName(Name +
".coerce");
1893 V = CGF.
Builder.CreateExtractVector(ToTy,
V, uint64_t(0),
"cast.fixed");
1903class ClangToLLVMArgMapping {
1904 static const unsigned InvalidIndex = ~0U;
1905 unsigned InallocaArgNo;
1907 unsigned TotalIRArgs;
1911 unsigned PaddingArgIndex;
1914 unsigned FirstArgIndex;
1915 unsigned NumberOfArgs;
1918 : PaddingArgIndex(InvalidIndex), FirstArgIndex(InvalidIndex),
1922 SmallVector<IRArgs, 8> ArgInfo;
1925 ClangToLLVMArgMapping(
const ASTContext &Context,
const CGFunctionInfo &FI,
1926 bool OnlyRequiredArgs =
false)
1927 : InallocaArgNo(InvalidIndex), SRetArgNo(InvalidIndex), TotalIRArgs(0),
1928 ArgInfo(OnlyRequiredArgs ? FI.getNumRequiredArgs() : FI.arg_size()) {
1929 construct(Context, FI, OnlyRequiredArgs);
1932 bool hasInallocaArg()
const {
return InallocaArgNo != InvalidIndex; }
1933 unsigned getInallocaArgNo()
const {
1934 assert(hasInallocaArg());
1935 return InallocaArgNo;
1938 bool hasSRetArg()
const {
return SRetArgNo != InvalidIndex; }
1939 unsigned getSRetArgNo()
const {
1940 assert(hasSRetArg());
1944 unsigned totalIRArgs()
const {
return TotalIRArgs; }
1946 bool hasPaddingArg(
unsigned ArgNo)
const {
1947 assert(ArgNo < ArgInfo.size());
1948 return ArgInfo[ArgNo].PaddingArgIndex != InvalidIndex;
1950 unsigned getPaddingArgNo(
unsigned ArgNo)
const {
1951 assert(hasPaddingArg(ArgNo));
1952 return ArgInfo[ArgNo].PaddingArgIndex;
1957 std::pair<unsigned, unsigned> getIRArgs(
unsigned ArgNo)
const {
1958 assert(ArgNo < ArgInfo.size());
1959 return std::make_pair(ArgInfo[ArgNo].FirstArgIndex,
1960 ArgInfo[ArgNo].NumberOfArgs);
1964 void construct(
const ASTContext &Context,
const CGFunctionInfo &FI,
1965 bool OnlyRequiredArgs);
1968void ClangToLLVMArgMapping::construct(
const ASTContext &Context,
1969 const CGFunctionInfo &FI,
1970 bool OnlyRequiredArgs) {
1971 unsigned IRArgNo = 0;
1972 bool SwapThisWithSRet =
false;
1977 SRetArgNo = SwapThisWithSRet ? 1 : IRArgNo++;
1985 QualType ArgType = I->type;
1986 const ABIArgInfo &AI = I->info;
1988 auto &IRArgs = ArgInfo[ArgNo];
1991 IRArgs.PaddingArgIndex = IRArgNo++;
1998 llvm::StructType *STy = dyn_cast<llvm::StructType>(AI.
getCoerceToType());
2000 IRArgs.NumberOfArgs = STy->getNumElements();
2002 IRArgs.NumberOfArgs = 1;
2008 IRArgs.NumberOfArgs = 1;
2013 IRArgs.NumberOfArgs = 0;
2023 if (IRArgs.NumberOfArgs > 0) {
2024 IRArgs.FirstArgIndex = IRArgNo;
2025 IRArgNo += IRArgs.NumberOfArgs;
2030 if (IRArgNo == 1 && SwapThisWithSRet)
2033 assert(ArgNo == ArgInfo.size());
2036 InallocaArgNo = IRArgNo++;
2038 TotalIRArgs = IRArgNo;
2046 return RI.
isIndirect() || (RI.isInAlloca() && RI.getInAllocaSRet());
2061 switch (BT->getKind()) {
2064 case BuiltinType::Float:
2066 case BuiltinType::Double:
2068 case BuiltinType::LongDouble:
2079 if (BT->getKind() == BuiltinType::LongDouble)
2080 return getTarget().useObjCFP2RetForComplexLongDouble();
2094 bool Inserted = FunctionsBeingProcessed.insert(&FI).second;
2096 assert(Inserted &&
"Recursively being processed?");
2098 llvm::Type *resultType =
nullptr;
2103 llvm_unreachable(
"Invalid ABI kind for return argument");
2115 unsigned addressSpace = CGM.getTypes().getTargetAddressSpace(ret);
2116 resultType = llvm::PointerType::get(
getLLVMContext(), addressSpace);
2132 ClangToLLVMArgMapping IRFunctionArgs(
getContext(), FI,
true);
2136 if (IRFunctionArgs.hasSRetArg()) {
2137 ArgTypes[IRFunctionArgs.getSRetArgNo()] = llvm::PointerType::get(
2142 if (IRFunctionArgs.hasInallocaArg())
2143 ArgTypes[IRFunctionArgs.getInallocaArgNo()] =
2150 for (; it != ie; ++it, ++ArgNo) {
2154 if (IRFunctionArgs.hasPaddingArg(ArgNo))
2155 ArgTypes[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
2158 unsigned FirstIRArg, NumIRArgs;
2159 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
2164 assert(NumIRArgs == 0);
2168 assert(NumIRArgs == 1);
2170 ArgTypes[FirstIRArg] = llvm::PointerType::get(
2174 assert(NumIRArgs == 1);
2175 ArgTypes[FirstIRArg] = llvm::PointerType::get(
2184 llvm::StructType *st = dyn_cast<llvm::StructType>(argType);
2186 assert(NumIRArgs == st->getNumElements());
2187 for (
unsigned i = 0, e = st->getNumElements(); i != e; ++i)
2188 ArgTypes[FirstIRArg + i] = st->getElementType(i);
2190 assert(NumIRArgs == 1);
2191 ArgTypes[FirstIRArg] = argType;
2197 auto ArgTypesIter = ArgTypes.begin() + FirstIRArg;
2199 *ArgTypesIter++ = EltTy;
2201 assert(ArgTypesIter == ArgTypes.begin() + FirstIRArg + NumIRArgs);
2206 auto ArgTypesIter = ArgTypes.begin() + FirstIRArg;
2208 assert(ArgTypesIter == ArgTypes.begin() + FirstIRArg + NumIRArgs);
2213 bool Erased = FunctionsBeingProcessed.erase(&FI);
2215 assert(Erased &&
"Not in set?");
2217 return llvm::FunctionType::get(resultType, ArgTypes, FI.
isVariadic());
2231 llvm::AttrBuilder &FuncAttrs,
2238 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2242 FuncAttrs.addAttribute(
"aarch64_pstate_sm_enabled");
2244 FuncAttrs.addAttribute(
"aarch64_pstate_sm_compatible");
2246 FuncAttrs.addAttribute(
"aarch64_za_state_agnostic");
2250 FuncAttrs.addAttribute(
"aarch64_preserves_za");
2252 FuncAttrs.addAttribute(
"aarch64_in_za");
2254 FuncAttrs.addAttribute(
"aarch64_out_za");
2256 FuncAttrs.addAttribute(
"aarch64_inout_za");
2260 FuncAttrs.addAttribute(
"aarch64_preserves_zt0");
2262 FuncAttrs.addAttribute(
"aarch64_in_zt0");
2264 FuncAttrs.addAttribute(
"aarch64_out_zt0");
2266 FuncAttrs.addAttribute(
"aarch64_inout_zt0");
2270 const Decl *Callee) {
2276 for (
const OMPAssumeAttr *AA : Callee->specific_attrs<OMPAssumeAttr>())
2277 AA->getAssumption().split(Attrs,
",");
2280 FuncAttrs.addAttribute(llvm::AssumptionAttrKey,
2281 llvm::join(Attrs.begin(), Attrs.end(),
","));
2288 if (
const RecordType *RT =
2290 if (
const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl()))
2291 return ClassDecl->hasTrivialDestructor();
2297 const Decl *TargetDecl) {
2303 if (
Module.getLangOpts().Sanitize.has(SanitizerKind::Memory))
2307 if (!
Module.getLangOpts().CPlusPlus)
2310 if (
const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(TargetDecl)) {
2311 if (FDecl->isExternC())
2313 }
else if (
const VarDecl *VDecl = dyn_cast<VarDecl>(TargetDecl)) {
2315 if (VDecl->isExternC())
2323 return Module.getCodeGenOpts().StrictReturn ||
2324 !
Module.MayDropFunctionReturn(
Module.getContext(), RetTy) ||
2325 Module.getLangOpts().Sanitize.has(SanitizerKind::Return);
2332 llvm::DenormalMode FP32DenormalMode,
2333 llvm::AttrBuilder &FuncAttrs) {
2334 llvm::DenormalFPEnv FPEnv(FPDenormalMode, FP32DenormalMode);
2335 if (FPEnv != llvm::DenormalFPEnv::getDefault())
2336 FuncAttrs.addDenormalFPEnvAttr(FPEnv);
2344 llvm::AttrBuilder &FuncAttrs) {
2350 StringRef Name,
bool HasOptnone,
const CodeGenOptions &CodeGenOpts,
2352 llvm::AttrBuilder &FuncAttrs) {
2355 if (CodeGenOpts.OptimizeSize)
2356 FuncAttrs.addAttribute(llvm::Attribute::OptimizeForSize);
2357 if (CodeGenOpts.OptimizeSize == 2)
2358 FuncAttrs.addAttribute(llvm::Attribute::MinSize);
2361 if (CodeGenOpts.DisableRedZone)
2362 FuncAttrs.addAttribute(llvm::Attribute::NoRedZone);
2363 if (CodeGenOpts.IndirectTlsSegRefs)
2364 FuncAttrs.addAttribute(
"indirect-tls-seg-refs");
2365 if (CodeGenOpts.NoImplicitFloat)
2366 FuncAttrs.addAttribute(llvm::Attribute::NoImplicitFloat);
2368 if (AttrOnCallSite) {
2373 FuncAttrs.addAttribute(llvm::Attribute::NoBuiltin);
2375 FuncAttrs.addAttribute(
"trap-func-name", CodeGenOpts.
TrapFuncName);
2377 switch (CodeGenOpts.getFramePointer()) {
2385 FuncAttrs.addAttribute(
"frame-pointer",
2387 CodeGenOpts.getFramePointer()));
2390 if (CodeGenOpts.LessPreciseFPMAD)
2391 FuncAttrs.addAttribute(
"less-precise-fpmad",
"true");
2393 if (CodeGenOpts.NullPointerIsValid)
2394 FuncAttrs.addAttribute(llvm::Attribute::NullPointerIsValid);
2397 FuncAttrs.addAttribute(
"no-trapping-math",
"true");
2401 if (CodeGenOpts.SoftFloat)
2402 FuncAttrs.addAttribute(
"use-soft-float",
"true");
2403 FuncAttrs.addAttribute(
"stack-protector-buffer-size",
2404 llvm::utostr(CodeGenOpts.SSPBufferSize));
2405 if (LangOpts.NoSignedZero)
2406 FuncAttrs.addAttribute(
"no-signed-zeros-fp-math",
"true");
2409 const std::vector<std::string> &Recips = CodeGenOpts.
Reciprocals;
2410 if (!Recips.empty())
2411 FuncAttrs.addAttribute(
"reciprocal-estimates", llvm::join(Recips,
","));
2415 FuncAttrs.addAttribute(
"prefer-vector-width",
2418 if (CodeGenOpts.StackRealignment)
2419 FuncAttrs.addAttribute(
"stackrealign");
2420 if (CodeGenOpts.Backchain)
2421 FuncAttrs.addAttribute(
"backchain");
2422 if (CodeGenOpts.EnableSegmentedStacks)
2423 FuncAttrs.addAttribute(
"split-stack");
2425 if (CodeGenOpts.SpeculativeLoadHardening)
2426 FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
2429 switch (CodeGenOpts.getZeroCallUsedRegs()) {
2430 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Skip:
2431 FuncAttrs.removeAttribute(
"zero-call-used-regs");
2433 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPRArg:
2434 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used-gpr-arg");
2436 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPR:
2437 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used-gpr");
2439 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedArg:
2440 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used-arg");
2442 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Used:
2443 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used");
2445 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPRArg:
2446 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all-gpr-arg");
2448 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPR:
2449 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all-gpr");
2451 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllArg:
2452 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all-arg");
2454 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::All:
2455 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all");
2466 FuncAttrs.addAttribute(llvm::Attribute::Convergent);
2471 if ((LangOpts.CUDA && LangOpts.CUDAIsDevice) || LangOpts.OpenCL ||
2472 LangOpts.SYCLIsDevice) {
2473 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2476 if (CodeGenOpts.SaveRegParams && !AttrOnCallSite)
2477 FuncAttrs.addAttribute(
"save-reg-params");
2480 StringRef Var,
Value;
2482 FuncAttrs.addAttribute(Var,
Value);
2485 if (!AttrOnCallSite) {
2498 const llvm::Function &F,
2500 auto FFeatures = F.getFnAttribute(
"target-features");
2502 llvm::StringSet<> MergedNames;
2504 MergedFeatures.reserve(TargetOpts.
Features.size());
2506 auto AddUnmergedFeatures = [&](
auto &&FeatureRange) {
2507 for (StringRef
Feature : FeatureRange) {
2511 StringRef Name =
Feature.drop_front(1);
2512 bool Merged = !MergedNames.insert(Name).second;
2514 MergedFeatures.push_back(
Feature);
2518 if (FFeatures.isValid())
2519 AddUnmergedFeatures(llvm::split(FFeatures.getValueAsString(),
','));
2520 AddUnmergedFeatures(TargetOpts.
Features);
2522 if (!MergedFeatures.empty()) {
2523 llvm::sort(MergedFeatures);
2524 FuncAttr.addAttribute(
"target-features", llvm::join(MergedFeatures,
","));
2531 bool WillInternalize) {
2533 llvm::AttrBuilder FuncAttrs(F.getContext());
2536 if (!TargetOpts.
CPU.empty())
2537 FuncAttrs.addAttribute(
"target-cpu", TargetOpts.
CPU);
2538 if (!TargetOpts.
TuneCPU.empty())
2539 FuncAttrs.addAttribute(
"tune-cpu", TargetOpts.
TuneCPU);
2542 CodeGenOpts, LangOpts,
2545 if (!WillInternalize && F.isInterposable()) {
2550 F.addFnAttrs(FuncAttrs);
2554 llvm::AttributeMask AttrsToRemove;
2558 llvm::DenormalFPEnv MergedFPEnv =
2559 OptsFPEnv.mergeCalleeMode(F.getDenormalFPEnv());
2561 if (MergedFPEnv == llvm::DenormalFPEnv::getDefault()) {
2562 AttrsToRemove.addAttribute(llvm::Attribute::DenormalFPEnv);
2565 FuncAttrs.addDenormalFPEnvAttr(MergedFPEnv);
2568 F.removeFnAttrs(AttrsToRemove);
2572 F.addFnAttrs(FuncAttrs);
2575void CodeGenModule::getTrivialDefaultFunctionAttributes(
2576 StringRef Name,
bool HasOptnone,
bool AttrOnCallSite,
2577 llvm::AttrBuilder &FuncAttrs) {
2579 getLangOpts(), AttrOnCallSite,
2583void CodeGenModule::getDefaultFunctionAttributes(StringRef Name,
2585 bool AttrOnCallSite,
2586 llvm::AttrBuilder &FuncAttrs) {
2590 if (!AttrOnCallSite)
2596 if (!AttrOnCallSite)
2601 llvm::AttrBuilder &attrs) {
2602 getDefaultFunctionAttributes(
"",
false,
2604 GetCPUAndFeaturesAttributes(
GlobalDecl(), attrs);
2609 const NoBuiltinAttr *NBA =
nullptr) {
2610 auto AddNoBuiltinAttr = [&FuncAttrs](StringRef BuiltinName) {
2612 AttributeName +=
"no-builtin-";
2613 AttributeName += BuiltinName;
2614 FuncAttrs.addAttribute(AttributeName);
2618 if (LangOpts.NoBuiltin) {
2620 FuncAttrs.addAttribute(
"no-builtins");
2634 if (llvm::is_contained(NBA->builtinNames(),
"*")) {
2635 FuncAttrs.addAttribute(
"no-builtins");
2640 llvm::for_each(NBA->builtinNames(), AddNoBuiltinAttr);
2644 const llvm::DataLayout &DL,
const ABIArgInfo &AI,
2645 bool CheckCoerce =
true) {
2652 if (!DL.typeSizeEqualsStoreSize(Ty))
2659 if (llvm::TypeSize::isKnownGT(DL.getTypeSizeInBits(CoerceTy),
2660 DL.getTypeSizeInBits(Ty)))
2684 if (
const MatrixType *Matrix = dyn_cast<MatrixType>(QTy))
2695 unsigned NumRequiredArgs,
unsigned ArgNo) {
2696 const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl);
2701 if (ArgNo >= NumRequiredArgs)
2705 if (ArgNo < FD->getNumParams()) {
2706 const ParmVarDecl *Param = FD->getParamDecl(ArgNo);
2707 if (Param && Param->hasAttr<MaybeUndefAttr>())
2724 if (llvm::AttributeFuncs::isNoFPClassCompatibleType(IRTy))
2727 if (llvm::StructType *ST = dyn_cast<llvm::StructType>(IRTy)) {
2729 llvm::all_of(ST->elements(),
2730 llvm::AttributeFuncs::isNoFPClassCompatibleType);
2738 llvm::AttributeList &Attrs) {
2739 if (Attrs.getMemoryEffects().getModRef() == llvm::ModRefInfo::NoModRef) {
2740 Attrs = Attrs.removeFnAttribute(
getLLVMContext(), llvm::Attribute::Memory);
2741 llvm::Attribute MemoryAttr = llvm::Attribute::getWithMemoryEffects(
2767 llvm::AttributeList &AttrList,
2769 bool AttrOnCallSite,
bool IsThunk) {
2777 FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2779 FuncAttrs.addAttribute(
"cmse_nonsecure_call");
2790 bool HasOptnone =
false;
2792 const NoBuiltinAttr *NBA =
nullptr;
2796 std::optional<llvm::Attribute::AttrKind> MemAttrForPtrArgs;
2797 bool AddedPotentialArgAccess =
false;
2798 auto AddPotentialArgAccess = [&]() {
2799 AddedPotentialArgAccess =
true;
2800 llvm::Attribute A = FuncAttrs.getAttribute(llvm::Attribute::Memory);
2802 FuncAttrs.addMemoryAttr(A.getMemoryEffects() |
2803 llvm::MemoryEffects::argMemOnly());
2810 if (TargetDecl->
hasAttr<ReturnsTwiceAttr>())
2811 FuncAttrs.addAttribute(llvm::Attribute::ReturnsTwice);
2812 if (TargetDecl->
hasAttr<NoThrowAttr>())
2813 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2814 if (TargetDecl->
hasAttr<NoReturnAttr>())
2815 FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2816 if (TargetDecl->
hasAttr<ColdAttr>())
2817 FuncAttrs.addAttribute(llvm::Attribute::Cold);
2818 if (TargetDecl->
hasAttr<HotAttr>())
2819 FuncAttrs.addAttribute(llvm::Attribute::Hot);
2820 if (TargetDecl->
hasAttr<NoDuplicateAttr>())
2821 FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate);
2822 if (TargetDecl->
hasAttr<ConvergentAttr>())
2823 FuncAttrs.addAttribute(llvm::Attribute::Convergent);
2825 if (
const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
2828 if (AttrOnCallSite && Fn->isReplaceableGlobalAllocationFunction()) {
2831 Fn->getDeclName().isAnyOperatorNew())
2832 RetAttrs.addAttribute(llvm::Attribute::NoAlias);
2835 const bool IsVirtualCall = MD && MD->
isVirtual();
2838 if (!(AttrOnCallSite && IsVirtualCall)) {
2839 if (Fn->isNoReturn())
2840 FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2841 NBA = Fn->getAttr<NoBuiltinAttr>();
2848 if (AttrOnCallSite && TargetDecl->
hasAttr<NoMergeAttr>())
2849 FuncAttrs.addAttribute(llvm::Attribute::NoMerge);
2853 if (TargetDecl->
hasAttr<ConstAttr>()) {
2854 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::none());
2855 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2858 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
2859 MemAttrForPtrArgs = llvm::Attribute::ReadNone;
2860 }
else if (TargetDecl->
hasAttr<PureAttr>()) {
2861 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
2862 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2864 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
2865 MemAttrForPtrArgs = llvm::Attribute::ReadOnly;
2866 }
else if (TargetDecl->
hasAttr<NoAliasAttr>()) {
2867 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::inaccessibleOrArgMemOnly());
2868 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2870 if (
const auto *RA = TargetDecl->
getAttr<RestrictAttr>();
2871 RA && RA->getDeallocator() ==
nullptr)
2872 RetAttrs.addAttribute(llvm::Attribute::NoAlias);
2873 if (TargetDecl->
hasAttr<ReturnsNonNullAttr>() &&
2874 !CodeGenOpts.NullPointerIsValid)
2875 RetAttrs.addAttribute(llvm::Attribute::NonNull);
2876 if (TargetDecl->
hasAttr<AnyX86NoCallerSavedRegistersAttr>())
2877 FuncAttrs.addAttribute(
"no_caller_saved_registers");
2878 if (TargetDecl->
hasAttr<AnyX86NoCfCheckAttr>())
2879 FuncAttrs.addAttribute(llvm::Attribute::NoCfCheck);
2880 if (TargetDecl->
hasAttr<LeafAttr>())
2881 FuncAttrs.addAttribute(llvm::Attribute::NoCallback);
2882 if (TargetDecl->
hasAttr<BPFFastCallAttr>())
2883 FuncAttrs.addAttribute(
"bpf_fastcall");
2885 HasOptnone = TargetDecl->
hasAttr<OptimizeNoneAttr>();
2886 if (
auto *AllocSize = TargetDecl->
getAttr<AllocSizeAttr>()) {
2887 std::optional<unsigned> NumElemsParam;
2888 if (AllocSize->getNumElemsParam().isValid())
2889 NumElemsParam = AllocSize->getNumElemsParam().getLLVMIndex();
2890 FuncAttrs.addAllocSizeAttr(AllocSize->getElemSizeParam().getLLVMIndex(),
2900 FuncAttrs.addAttribute(
"uniform-work-group-size");
2902 if (TargetDecl->
hasAttr<ArmLocallyStreamingAttr>())
2903 FuncAttrs.addAttribute(
"aarch64_pstate_sm_body");
2905 if (
auto *ModularFormat = TargetDecl->
getAttr<ModularFormatAttr>()) {
2906 FormatAttr *Format = TargetDecl->
getAttr<FormatAttr>();
2907 StringRef
Type = Format->getType()->getName();
2908 std::string FormatIdx = std::to_string(Format->getFormatIdx());
2909 std::string FirstArg = std::to_string(Format->getFirstArg());
2911 Type, FormatIdx, FirstArg,
2912 ModularFormat->getModularImplFn()->getName(),
2913 ModularFormat->getImplName()};
2914 llvm::append_range(Args, ModularFormat->aspects());
2915 FuncAttrs.addAttribute(
"modular-format", llvm::join(Args,
","));
2928 getDefaultFunctionAttributes(Name, HasOptnone, AttrOnCallSite, FuncAttrs);
2933 if (TargetDecl->
hasAttr<NoSpeculativeLoadHardeningAttr>())
2934 FuncAttrs.removeAttribute(llvm::Attribute::SpeculativeLoadHardening);
2935 if (TargetDecl->
hasAttr<SpeculativeLoadHardeningAttr>())
2936 FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
2937 if (TargetDecl->
hasAttr<NoSplitStackAttr>())
2938 FuncAttrs.removeAttribute(
"split-stack");
2939 if (TargetDecl->
hasAttr<ZeroCallUsedRegsAttr>()) {
2942 TargetDecl->
getAttr<ZeroCallUsedRegsAttr>()->getZeroCallUsedRegs();
2943 FuncAttrs.removeAttribute(
"zero-call-used-regs");
2944 FuncAttrs.addAttribute(
2945 "zero-call-used-regs",
2946 ZeroCallUsedRegsAttr::ConvertZeroCallUsedRegsKindToStr(Kind));
2953 if (CodeGenOpts.NoPLT) {
2954 if (
auto *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
2955 if (!Fn->isDefined() && !AttrOnCallSite) {
2956 FuncAttrs.addAttribute(llvm::Attribute::NonLazyBind);
2961 if (TargetDecl->
hasAttr<NoConvergentAttr>())
2962 FuncAttrs.removeAttribute(llvm::Attribute::Convergent);
2967 if (TargetDecl && CodeGenOpts.UniqueInternalLinkageNames) {
2968 if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
2969 if (!FD->isExternallyVisible())
2970 FuncAttrs.addAttribute(
"sample-profile-suffix-elision-policy",
2977 if (!AttrOnCallSite) {
2978 if (TargetDecl && TargetDecl->
hasAttr<CmseNSEntryAttr>())
2979 FuncAttrs.addAttribute(
"cmse_nonsecure_entry");
2982 auto shouldDisableTailCalls = [&] {
2984 if (CodeGenOpts.DisableTailCalls)
2990 if (TargetDecl->
hasAttr<DisableTailCallsAttr>() ||
2991 TargetDecl->
hasAttr<AnyX86InterruptAttr>())
2994 if (CodeGenOpts.NoEscapingBlockTailCalls) {
2995 if (
const auto *BD = dyn_cast<BlockDecl>(TargetDecl))
2996 if (!BD->doesNotEscape())
3002 if (shouldDisableTailCalls())
3003 FuncAttrs.addAttribute(
"disable-tail-calls",
"true");
3008 static const llvm::StringSet<> ReturnsTwiceFn{
3009 "_setjmpex",
"setjmp",
"_setjmp",
"vfork",
3010 "sigsetjmp",
"__sigsetjmp",
"savectx",
"getcontext"};
3011 if (ReturnsTwiceFn.contains(Name))
3012 FuncAttrs.addAttribute(llvm::Attribute::ReturnsTwice);
3016 GetCPUAndFeaturesAttributes(CalleeInfo.
getCalleeDecl(), FuncAttrs);
3019 if (!MSHotPatchFunctions.empty()) {
3020 bool IsHotPatched = llvm::binary_search(MSHotPatchFunctions, Name);
3022 FuncAttrs.addAttribute(
"marked_for_windows_hot_patching");
3027 if (CodeGenOpts.isLoaderReplaceableFunctionName(Name))
3028 FuncAttrs.addAttribute(
"loader-replaceable");
3031 ClangToLLVMArgMapping IRFunctionArgs(
getContext(), FI);
3038 if (CodeGenOpts.EnableNoundefAttrs &&
3042 RetAttrs.addAttribute(llvm::Attribute::NoUndef);
3048 RetAttrs.addAttribute(llvm::Attribute::SExt);
3050 RetAttrs.addAttribute(llvm::Attribute::ZExt);
3052 RetAttrs.addAttribute(llvm::Attribute::NoExt);
3057 RetAttrs.addAttribute(llvm::Attribute::InReg);
3060 RetAttrs.addNoFPClassAttr(
3070 AddPotentialArgAccess();
3079 llvm_unreachable(
"Invalid ABI kind for return argument");
3087 RetAttrs.addDereferenceableAttr(
3089 if (
getTypes().getTargetAddressSpace(PTy) == 0 &&
3090 !CodeGenOpts.NullPointerIsValid)
3091 RetAttrs.addAttribute(llvm::Attribute::NonNull);
3093 llvm::Align Alignment =
3095 RetAttrs.addAlignmentAttr(Alignment);
3100 bool hasUsedSRet =
false;
3102 for (
unsigned I = 0; I < IRFunctionArgs.totalIRArgs(); ++I)
3106 if (IRFunctionArgs.hasSRetArg()) {
3107 llvm::AttrBuilder &SRETAttrs = ArgAttrs[IRFunctionArgs.getSRetArgNo()];
3108 SRETAttrs.addStructRetAttr(
getTypes().ConvertTypeForMem(RetTy));
3109 SRETAttrs.addAttribute(llvm::Attribute::Writable);
3110 SRETAttrs.addAttribute(llvm::Attribute::DeadOnUnwind);
3113 SRETAttrs.addAttribute(llvm::Attribute::InReg);
3118 if (IRFunctionArgs.hasInallocaArg()) {
3119 ArgAttrs[IRFunctionArgs.getInallocaArgNo()].addInAllocaAttr(
3129 auto IRArgs = IRFunctionArgs.getIRArgs(0);
3131 assert(IRArgs.second == 1 &&
"Expected only a single `this` pointer.");
3133 llvm::AttrBuilder &Attrs = ArgAttrs[IRArgs.first];
3138 if (!CodeGenOpts.NullPointerIsValid &&
3140 Attrs.addAttribute(llvm::Attribute::NonNull);
3141 Attrs.addDereferenceableAttr(ThisSz);
3147 Attrs.addDereferenceableOrNullAttr(ThisSz);
3150 llvm::Align Alignment =
3154 Attrs.addAlignmentAttr(Alignment);
3156 const auto *DD = dyn_cast_if_present<CXXDestructorDecl>(
3170 CodeGenOpts.StrictLifetimes) {
3172 dyn_cast<CXXRecordDecl>(DD->getDeclContext());
3176 Attrs.addDeadOnReturnAttr(llvm::DeadOnReturnInfo(
3177 Context.getASTRecordLayout(ClassDecl).getDataSize().getQuantity()));
3183 I != E; ++I, ++ArgNo) {
3189 if (IRFunctionArgs.hasPaddingArg(ArgNo)) {
3191 ArgAttrs[IRFunctionArgs.getPaddingArgNo(ArgNo)].addAttribute(
3192 llvm::Attribute::InReg);
3197 if (CodeGenOpts.EnableNoundefAttrs &&
3199 Attrs.addAttribute(llvm::Attribute::NoUndef);
3208 Attrs.addAttribute(llvm::Attribute::SExt);
3210 Attrs.addAttribute(llvm::Attribute::ZExt);
3212 Attrs.addAttribute(llvm::Attribute::NoExt);
3217 Attrs.addAttribute(llvm::Attribute::Nest);
3219 Attrs.addAttribute(llvm::Attribute::InReg);
3220 Attrs.addStackAlignmentAttr(llvm::MaybeAlign(AI.
getDirectAlign()));
3223 Attrs.addNoFPClassAttr(
3228 "Pass-by-value parameter has incomplete definition?");
3231 Attrs.addAttribute(llvm::Attribute::InReg);
3243 Attrs.addByValAttr(
getTypes().ConvertTypeForMem(ParamType));
3251 Attrs.addDeadOnReturnAttr(llvm::DeadOnReturnInfo());
3256 if (CodeGenOpts.PassByValueIsNoAlias &&
Decl &&
3257 Decl->getArgPassingRestrictions() ==
3261 Attrs.addAttribute(llvm::Attribute::NoAlias);
3291 Attrs.addAttribute(llvm::Attribute::NoFreeObj);
3292 Attrs.addDereferenceableAttr(
3293 Context.getTypeSizeInChars(ParamType).getQuantity());
3297 AddPotentialArgAccess();
3302 Attrs.addByRefAttr(
getTypes().ConvertTypeForMem(ParamType));
3313 AddPotentialArgAccess();
3321 if (
getTypes().getTargetAddressSpace(PTy) == 0 &&
3322 !CodeGenOpts.NullPointerIsValid)
3323 Attrs.addAttribute(llvm::Attribute::NonNull);
3325 llvm::Align Alignment =
3327 Attrs.addAlignmentAttr(Alignment);
3336 DeviceKernelAttr::isOpenCLSpelling(
3337 TargetDecl->
getAttr<DeviceKernelAttr>()) &&
3341 llvm::Align Alignment =
3343 Attrs.addAlignmentAttr(Alignment);
3350 Attrs.addAttribute(llvm::Attribute::NoAlias);
3359 Attrs.addStructRetAttr(
getTypes().ConvertTypeForMem(ParamType));
3364 Attrs.addAttribute(llvm::Attribute::NoAlias);
3368 if (!PTy->isIncompleteType() && PTy->isConstantSizeType()) {
3369 auto info =
getContext().getTypeInfoInChars(PTy);
3370 Attrs.addDereferenceableAttr(info.Width.getQuantity());
3371 Attrs.addAlignmentAttr(info.Align.getAsAlign());
3377 Attrs.addAttribute(llvm::Attribute::SwiftError);
3381 Attrs.addAttribute(llvm::Attribute::SwiftSelf);
3385 Attrs.addAttribute(llvm::Attribute::SwiftAsync);
3390 Attrs.addCapturesAttr(
3391 llvm::CaptureInfo(llvm::CaptureComponents::Address));
3393 if (Attrs.hasAttributes()) {
3394 unsigned FirstIRArg, NumIRArgs;
3395 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
3396 for (
unsigned i = 0; i < NumIRArgs; i++)
3397 ArgAttrs[FirstIRArg + i].merge(Attrs);
3405 AddPotentialArgAccess();
3408 if (AddedPotentialArgAccess && MemAttrForPtrArgs) {
3412 I != E; ++I, ++ArgNo) {
3413 if (I->info.isDirect() || I->info.isExpand() ||
3414 I->info.isCoerceAndExpand()) {
3415 unsigned FirstIRArg, NumIRArgs;
3416 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
3417 for (
unsigned i = FirstIRArg; i < FirstIRArg + NumIRArgs; ++i) {
3424 if (i < FunctionType->getNumParams() &&
3426 ArgAttrs[i].addAttribute(*MemAttrForPtrArgs);
3434 for (
const llvm::AttrBuilder &Attrs : ArgAttrs)
3435 ArgAttrSets.push_back(llvm::AttributeSet::get(
getLLVMContext(), Attrs));
3437 AttrList = llvm::AttributeList::get(
3439 llvm::AttributeSet::get(
getLLVMContext(), RetAttrs), ArgAttrSets);
3446 llvm::Value *value) {
3447 llvm::Type *varType = CGF.
ConvertType(var->getType());
3451 if (value->getType() == varType)
3454 assert((varType->isIntegerTy() || varType->isFloatingPointTy()) &&
3455 "unexpected promotion type");
3458 return CGF.
Builder.CreateTrunc(value, varType,
"arg.unpromote");
3460 return CGF.
Builder.CreateFPCast(value, varType,
"arg.unpromote");
3466 QualType ArgType,
unsigned ArgNo) {
3474 if (!ArgType->isAnyPointerType() && !ArgType->isBlockPointerType())
3478 if (
auto ParmNNAttr = PVD->
getAttr<NonNullAttr>())
3485 if (NNAttr->isNonNull(ArgNo))
3492struct CopyBackSwiftError final : EHScopeStack::Cleanup {
3495 CopyBackSwiftError(Address temp, Address arg) : Temp(temp), Arg(
arg) {}
3496 void Emit(CodeGenFunction &CGF, Flags flags)
override {
3515 if (FD->hasImplicitReturnZero()) {
3516 QualType RetTy = FD->getReturnType().getUnqualifiedType();
3517 llvm::Type *LLVMTy =
CGM.getTypes().ConvertType(RetTy);
3518 llvm::Constant *
Zero = llvm::Constant::getNullValue(LLVMTy);
3526 ClangToLLVMArgMapping IRFunctionArgs(
CGM.getContext(), FI);
3527 assert(Fn->arg_size() == IRFunctionArgs.totalIRArgs());
3532 if (IRFunctionArgs.hasInallocaArg())
3533 ArgStruct =
Address(Fn->getArg(IRFunctionArgs.getInallocaArgNo()),
3537 if (IRFunctionArgs.hasSRetArg()) {
3538 auto AI = Fn->getArg(IRFunctionArgs.getSRetArgNo());
3539 AI->setName(
"agg.result");
3540 AI->addAttr(llvm::Attribute::NoAlias);
3547 ArgVals.reserve(Args.size());
3553 assert(FI.
arg_size() == Args.size() &&
3554 "Mismatch between function signature & arguments.");
3557 for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); i != e;
3558 ++i, ++info_it, ++ArgNo) {
3571 unsigned FirstIRArg, NumIRArgs;
3572 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
3576 assert(NumIRArgs == 0);
3589 assert(NumIRArgs == 1);
3612 llvm::ConstantInt::get(
IntPtrTy, Size.getQuantity()));
3613 ParamAddr = AlignedTemp;
3630 auto AI = Fn->getArg(FirstIRArg);
3638 assert(NumIRArgs == 1);
3640 if (
const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(Arg)) {
3643 PVD->getFunctionScopeIndex()) &&
3644 !
CGM.getCodeGenOpts().NullPointerIsValid)
3645 AI->addAttr(llvm::Attribute::NonNull);
3647 QualType OTy = PVD->getOriginalType();
3648 if (
const auto *ArrTy =
getContext().getAsConstantArrayType(OTy)) {
3654 QualType ETy = ArrTy->getElementType();
3655 llvm::Align Alignment =
3656 CGM.getNaturalTypeAlignment(ETy).getAsAlign();
3658 .addAlignmentAttr(Alignment));
3659 uint64_t ArrSize = ArrTy->getZExtSize();
3663 Attrs.addDereferenceableAttr(
3664 getContext().getTypeSizeInChars(ETy).getQuantity() *
3666 AI->addAttrs(Attrs);
3667 }
else if (
getContext().getTargetInfo().getNullPointerValue(
3669 !
CGM.getCodeGenOpts().NullPointerIsValid) {
3670 AI->addAttr(llvm::Attribute::NonNull);
3673 }
else if (
const auto *ArrTy =
3679 QualType ETy = ArrTy->getElementType();
3680 llvm::Align Alignment =
3681 CGM.getNaturalTypeAlignment(ETy).getAsAlign();
3683 .addAlignmentAttr(Alignment));
3684 if (!
getTypes().getTargetAddressSpace(ETy) &&
3685 !
CGM.getCodeGenOpts().NullPointerIsValid)
3686 AI->addAttr(llvm::Attribute::NonNull);
3691 const auto *AVAttr = PVD->getAttr<AlignValueAttr>();
3694 AVAttr = TOTy->getDecl()->getAttr<AlignValueAttr>();
3695 if (AVAttr && !
SanOpts.has(SanitizerKind::Alignment)) {
3699 llvm::ConstantInt *AlignmentCI =
3701 uint64_t AlignmentInt =
3702 AlignmentCI->getLimitedValue(llvm::Value::MaximumAlignment);
3703 if (AI->getParamAlign().valueOrOne() < AlignmentInt) {
3704 AI->removeAttr(llvm::Attribute::AttrKind::Alignment);
3706 .addAlignmentAttr(llvm::Align(AlignmentInt)));
3713 AI->addAttr(llvm::Attribute::NoAlias);
3721 assert(NumIRArgs == 1);
3725 llvm::Value *
V = AI;
3733 V, pointeeTy,
getContext().getTypeAlignInChars(pointeeTy));
3734 llvm::Value *incomingErrorValue =
Builder.CreateLoad(arg);
3735 Builder.CreateStore(incomingErrorValue, temp);
3756 if (
V->getType() != LTy)
3767 if (
auto *VecTyTo = dyn_cast<llvm::FixedVectorType>(
ConvertType(Ty))) {
3768 llvm::Value *ArgVal = Fn->getArg(FirstIRArg);
3769 if (
auto *VecTyFrom =
3770 dyn_cast<llvm::ScalableVectorType>(ArgVal->getType())) {
3772 *
this, VecTyTo, VecTyFrom, ArgVal, Arg->
getName());
3774 assert(NumIRArgs == 1);
3781 llvm::StructType *STy =
3792 STy->getNumElements() > 1) {
3793 llvm::TypeSize StructSize =
CGM.getDataLayout().getTypeAllocSize(STy);
3794 llvm::TypeSize PtrElementSize =
3795 CGM.getDataLayout().getTypeAllocSize(Ptr.getElementType());
3796 if (StructSize.isScalable()) {
3797 assert(STy->containsHomogeneousScalableVectorTypes() &&
3798 "ABI only supports structure with homogeneous scalable vector "
3800 assert(StructSize == PtrElementSize &&
3801 "Only allow non-fractional movement of structure with"
3802 "homogeneous scalable vector type");
3803 assert(STy->getNumElements() == NumIRArgs);
3805 llvm::Value *LoadedStructValue = llvm::PoisonValue::get(STy);
3806 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
3807 auto *AI = Fn->getArg(FirstIRArg + i);
3808 AI->setName(Arg->
getName() +
".coerce" + Twine(i));
3810 Builder.CreateInsertValue(LoadedStructValue, AI, i);
3813 Builder.CreateStore(LoadedStructValue, Ptr);
3815 uint64_t SrcSize = StructSize.getFixedValue();
3816 uint64_t DstSize = PtrElementSize.getFixedValue();
3819 if (SrcSize <= DstSize) {
3820 AddrToStoreInto = Ptr.withElementType(STy);
3826 assert(STy->getNumElements() == NumIRArgs);
3827 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
3828 auto AI = Fn->getArg(FirstIRArg + i);
3829 AI->setName(Arg->
getName() +
".coerce" + Twine(i));
3831 Builder.CreateStore(AI, EltPtr);
3834 if (SrcSize > DstSize) {
3835 Builder.CreateMemCpy(Ptr, AddrToStoreInto, DstSize);
3847 assert(NumIRArgs == 1);
3848 auto AI = Fn->getArg(FirstIRArg);
3849 AI->setName(Arg->
getName() +
".coerce");
3852 llvm::TypeSize::getFixed(
3853 getContext().getTypeSizeInChars(Ty).getQuantity() -
3879 auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
3883 unsigned argIndex = FirstIRArg;
3884 unsigned unpaddedIndex = 0;
3885 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
3886 llvm::Type *eltType = coercionType->getElementType(i);
3890 auto eltAddr =
Builder.CreateStructGEP(alloca, i);
3891 llvm::Value *elt = Fn->getArg(argIndex++);
3893 auto paramType = unpaddedStruct
3894 ? unpaddedStruct->getElementType(unpaddedIndex++)
3895 : unpaddedCoercionType;
3897 if (
auto *VecTyTo = dyn_cast<llvm::FixedVectorType>(eltType)) {
3898 if (
auto *VecTyFrom = dyn_cast<llvm::ScalableVectorType>(paramType)) {
3901 *
this, VecTyTo, VecTyFrom, elt, elt->getName());
3902 assert(Extracted &&
"Unexpected scalable to fixed vector coercion");
3905 Builder.CreateStore(elt, eltAddr);
3907 assert(argIndex == FirstIRArg + NumIRArgs);
3920 auto FnArgIter = Fn->arg_begin() + FirstIRArg;
3921 ExpandTypeFromArgs(Ty, LV, FnArgIter);
3922 assert(FnArgIter == Fn->arg_begin() + FirstIRArg + NumIRArgs);
3923 for (
unsigned i = 0, e = NumIRArgs; i != e; ++i) {
3924 auto AI = Fn->getArg(FirstIRArg + i);
3925 AI->setName(Arg->
getName() +
"." + Twine(i));
3931 auto *AI = Fn->getArg(FirstIRArg);
3932 AI->setName(Arg->
getName() +
".target_coerce");
3936 CGM.getABIInfo().createCoercedStore(AI, Ptr, ArgI,
false, *
this);
3950 assert(NumIRArgs == 0);
3963 if (
getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) {
3964 for (
int I = Args.size() - 1; I >= 0; --I)
3967 for (
unsigned I = 0, E = Args.size(); I != E; ++I)
3973 while (insn->use_empty()) {
3974 llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(insn);
3980 bitcast->eraseFromParent();
3986 llvm::Value *result) {
3988 llvm::BasicBlock *BB = CGF.
Builder.GetInsertBlock();
3991 if (&BB->back() != result)
3994 llvm::Type *resultType = result->getType();
4003 while (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(generator)) {
4009 if (generator->getNextNode() != bitcast)
4012 InstsToKill.push_back(bitcast);
4019 llvm::CallInst *call = dyn_cast<llvm::CallInst>(generator);
4023 bool doRetainAutorelease;
4026 doRetainAutorelease =
true;
4027 }
else if (call->getCalledOperand() ==
4029 doRetainAutorelease =
false;
4037 llvm::Instruction *prev = call->getPrevNode();
4040 prev = prev->getPrevNode();
4046 InstsToKill.push_back(prev);
4052 result = call->getArgOperand(0);
4053 InstsToKill.push_back(call);
4057 while (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(result)) {
4058 if (!bitcast->hasOneUse())
4060 InstsToKill.push_back(bitcast);
4061 result = bitcast->getOperand(0);
4065 for (
auto *I : InstsToKill)
4066 I->eraseFromParent();
4069 if (doRetainAutorelease)
4073 return CGF.
Builder.CreateBitCast(result, resultType);
4078 llvm::Value *result) {
4081 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurCodeDecl);
4090 llvm::CallInst *retainCall = dyn_cast<llvm::CallInst>(result);
4091 if (!retainCall || retainCall->getCalledOperand() !=
4096 llvm::Value *retainedValue = retainCall->getArgOperand(0);
4097 llvm::LoadInst *load =
4098 dyn_cast<llvm::LoadInst>(retainedValue->stripPointerCasts());
4099 if (!load || load->isAtomic() || load->isVolatile() ||
4106 llvm::Type *resultType = result->getType();
4108 assert(retainCall->use_empty());
4109 retainCall->eraseFromParent();
4112 return CGF.
Builder.CreateBitCast(load, resultType);
4119 llvm::Value *result) {
4142 auto GetStoreIfValid = [&CGF,
4143 ReturnValuePtr](llvm::User *
U) -> llvm::StoreInst * {
4144 auto *SI = dyn_cast<llvm::StoreInst>(
U);
4145 if (!SI || SI->getPointerOperand() != ReturnValuePtr ||
4151 assert(!SI->isAtomic() &&
4159 if (!ReturnValuePtr->hasOneUse()) {
4160 llvm::BasicBlock *IP = CGF.
Builder.GetInsertBlock();
4166 const llvm::Instruction *LoadIntoFakeUse =
nullptr;
4167 for (llvm::Instruction &I : llvm::reverse(*IP)) {
4171 if (LoadIntoFakeUse == &I)
4175 if (
auto *II = dyn_cast<llvm::IntrinsicInst>(&I)) {
4176 if (II->getIntrinsicID() == llvm::Intrinsic::lifetime_end)
4179 if (II->getIntrinsicID() == llvm::Intrinsic::fake_use) {
4180 LoadIntoFakeUse = dyn_cast<llvm::Instruction>(II->getArgOperand(0));
4184 return GetStoreIfValid(&I);
4189 llvm::StoreInst *store = GetStoreIfValid(ReturnValuePtr->user_back());
4195 llvm::BasicBlock *StoreBB = store->getParent();
4196 llvm::BasicBlock *IP = CGF.
Builder.GetInsertBlock();
4198 while (IP != StoreBB) {
4199 if (!SeenBBs.insert(IP).second || !(IP = IP->getSinglePredecessor()))
4215 int BitWidth,
int CharWidth) {
4216 assert(CharWidth <= 64);
4217 assert(
static_cast<unsigned>(BitWidth) <= Bits.size() * CharWidth);
4220 if (BitOffset >= CharWidth) {
4221 Pos += BitOffset / CharWidth;
4222 BitOffset = BitOffset % CharWidth;
4225 const uint64_t
Used = (uint64_t(1) << CharWidth) - 1;
4226 if (BitOffset + BitWidth >= CharWidth) {
4227 Bits[Pos++] |= (
Used << BitOffset) &
Used;
4228 BitWidth -= CharWidth - BitOffset;
4232 while (BitWidth >= CharWidth) {
4234 BitWidth -= CharWidth;
4238 Bits[Pos++] |= (
Used >> (CharWidth - BitWidth)) << BitOffset;
4246 int StorageSize,
int BitOffset,
int BitWidth,
4247 int CharWidth,
bool BigEndian) {
4250 setBitRange(TmpBits, BitOffset, BitWidth, CharWidth);
4253 std::reverse(TmpBits.begin(), TmpBits.end());
4255 for (uint64_t
V : TmpBits)
4256 Bits[StorageOffset++] |=
V;
4259static void setUsedBits(CodeGenModule &, QualType,
int,
4260 SmallVectorImpl<uint64_t> &);
4302 QualType ETy = Context.getBaseElementType(ATy);
4303 int Size = Context.getTypeSizeInChars(ETy).getQuantity();
4307 for (
int I = 0, N = Context.getConstantArrayElementCount(ATy); I < N; ++I) {
4308 auto Src = TmpBits.begin();
4309 auto Dst = Bits.begin() + Offset + I * Size;
4310 for (
int J = 0; J < Size; ++J)
4323 if (
const auto *ATy = Context.getAsConstantArrayType(QTy))
4326 int Size = Context.getTypeSizeInChars(QTy).getQuantity();
4330 std::fill_n(Bits.begin() + Offset, Size,
4331 (uint64_t(1) << Context.getCharWidth()) - 1);
4335 int Pos,
int Size,
int CharWidth,
4340 for (
auto P = Bits.begin() + Pos, E = Bits.begin() + Pos + Size; P != E;
4342 Mask = (Mask << CharWidth) | *P;
4344 auto P = Bits.begin() + Pos + Size, End = Bits.begin() + Pos;
4346 Mask = (Mask << CharWidth) | *--P;
4355 llvm::IntegerType *ITy,
4357 assert(Src->getType() == ITy);
4358 assert(ITy->getScalarSizeInBits() <= 64);
4360 const llvm::DataLayout &DataLayout =
CGM.getDataLayout();
4361 int Size = DataLayout.getTypeStoreSize(ITy);
4365 int CharWidth =
CGM.getContext().getCharWidth();
4369 return Builder.CreateAnd(Src, Mask,
"cmse.clear");
4375 llvm::ArrayType *ATy,
4377 const llvm::DataLayout &DataLayout =
CGM.getDataLayout();
4378 int Size = DataLayout.getTypeStoreSize(ATy);
4383 int CharWidth =
CGM.getContext().getCharWidth();
4385 ATy->getArrayElementType()->getScalarSizeInBits() / CharWidth;
4387 llvm::Value *R = llvm::PoisonValue::get(ATy);
4388 for (
int I = 0, N = ATy->getArrayNumElements(); I != N; ++I) {
4390 DataLayout.isBigEndian());
4391 MaskIndex += CharsPerElt;
4392 llvm::Value *T0 =
Builder.CreateExtractValue(Src, I);
4393 llvm::Value *T1 =
Builder.CreateAnd(T0, Mask,
"cmse.clear");
4394 R =
Builder.CreateInsertValue(R, T1, I);
4402 uint64_t RetKeyInstructionsSourceAtom) {
4417 auto *I =
Builder.CreateRetVoid();
4418 if (RetKeyInstructionsSourceAtom)
4425 llvm::DebugLoc RetDbgLoc;
4426 llvm::Value *RV =
nullptr;
4436 llvm::Function::arg_iterator EI =
CurFn->arg_end();
4438 llvm::Value *ArgStruct = &*EI;
4439 llvm::Value *SRet =
Builder.CreateStructGEP(
4448 auto AI =
CurFn->arg_begin();
4466 CGM.getNaturalTypeAlignment(RetTy, &BaseInfo, &TBAAInfo);
4493 RetDbgLoc = SI->getDebugLoc();
4495 RV = SI->getValueOperand();
4496 SI->eraseFromParent();
4519 if (
auto *FD = dyn_cast<FunctionDecl>(
CurCodeDecl))
4520 RT = FD->getReturnType();
4521 else if (
auto *MD = dyn_cast<ObjCMethodDecl>(
CurCodeDecl))
4522 RT = MD->getReturnType();
4524 RT =
BlockInfo->BlockExpression->getFunctionType()->getReturnType();
4526 llvm_unreachable(
"Unexpected function/method type");
4542 auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
4547 unsigned unpaddedIndex = 0;
4548 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
4549 auto coercedEltType = coercionType->getElementType(i);
4553 auto eltAddr =
Builder.CreateStructGEP(addr, i);
4556 unpaddedStruct ? unpaddedStruct->getElementType(unpaddedIndex++)
4557 : unpaddedCoercionType,
4559 results.push_back(elt);
4563 if (results.size() == 1) {
4571 RV = llvm::PoisonValue::get(returnType);
4572 for (
unsigned i = 0, e = results.size(); i != e; ++i) {
4573 RV =
Builder.CreateInsertValue(RV, results[i], i);
4580 RV =
CGM.getABIInfo().createCoercedLoad(
V, RetAI, *
this);
4585 llvm_unreachable(
"Invalid ABI kind for return argument");
4588 llvm::Instruction *Ret;
4594 auto *ITy = dyn_cast<llvm::IntegerType>(RV->getType());
4601 Ret =
Builder.CreateRetVoid();
4605 Ret->setDebugLoc(std::move(RetDbgLoc));
4607 llvm::Value *Backup = RV ? Ret->getOperand(0) :
nullptr;
4608 if (RetKeyInstructionsSourceAtom)
4624 ReturnsNonNullAttr *RetNNAttr =
nullptr;
4625 if (
SanOpts.has(SanitizerKind::ReturnsNonnullAttribute))
4626 RetNNAttr =
CurCodeDecl->getAttr<ReturnsNonNullAttr>();
4628 if (!RetNNAttr && !requiresReturnValueNullabilityCheck())
4636 assert(!requiresReturnValueNullabilityCheck() &&
4637 "Cannot check nullability and the nonnull attribute");
4638 AttrLoc = RetNNAttr->getLocation();
4639 CheckKind = SanitizerKind::SO_ReturnsNonnullAttribute;
4640 Handler = SanitizerHandler::NonnullReturn;
4642 if (
auto *DD = dyn_cast<DeclaratorDecl>(
CurCodeDecl))
4643 if (
auto *TSI = DD->getTypeSourceInfo())
4645 AttrLoc = FTL.getReturnLoc().findNullabilityLoc();
4646 CheckKind = SanitizerKind::SO_NullabilityReturn;
4647 Handler = SanitizerHandler::NullabilityReturn;
4656 llvm::Value *SLocPtr =
Builder.CreateLoad(ReturnLocation,
"return.sloc.load");
4657 llvm::Value *CanNullCheck =
Builder.CreateIsNotNull(SLocPtr);
4658 if (requiresReturnValueNullabilityCheck())
4660 Builder.CreateAnd(CanNullCheck, RetValNullabilityPrecondition);
4661 Builder.CreateCondBr(CanNullCheck, Check, NoCheck);
4665 llvm::Value *Cond =
Builder.CreateIsNotNull(RV);
4667 llvm::Value *DynamicData[] = {SLocPtr};
4668 EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, DynamicData);
4687 llvm::Type *IRPtrTy = llvm::PointerType::getUnqual(CGF.
getLLVMContext());
4688 llvm::Value *Placeholder = llvm::PoisonValue::get(IRPtrTy);
4713 if (
type->isReferenceType()) {
4722 param->
hasAttr<NSConsumedAttr>() &&
type->isObjCRetainableType()) {
4723 llvm::Value *ptr =
Builder.CreateLoad(local);
4726 Builder.CreateStore(null, local);
4737 type->castAsRecordDecl()->isParamDestroyedInCallee() &&
4741 assert(cleanup.isValid() &&
4742 "cleanup for callee-destructed param not recorded");
4744 llvm::Instruction *isActive =
4751 return llvm::isa_and_nonnull<llvm::ConstantPointerNull>(addr);
4761 const LValue &srcLV = writeback.
Source;
4762 Address srcAddr = srcLV.getAddress();
4764 "shouldn't have writeback for provably null argument");
4772 llvm::BasicBlock *contBB =
nullptr;
4778 if (!provablyNonNull) {
4783 CGF.
Builder.CreateCondBr(isNull, contBB, writebackBB);
4792 "icr.writeback-cast");
4801 if (writeback.
ToUse) {
4826 if (!provablyNonNull)
4835 for (
const auto &I : llvm::reverse(Cleanups)) {
4837 I.IsActiveIP->eraseFromParent();
4843 if (uop->getOpcode() == UO_AddrOf)
4844 return uop->getSubExpr();
4869 Address srcAddr = srcLV.getAddress();
4874 llvm::PointerType *destType =
4876 llvm::Type *destElemType =
4903 llvm::BasicBlock *contBB =
nullptr;
4904 llvm::BasicBlock *originBB =
nullptr;
4907 llvm::Value *finalArgument;
4911 if (provablyNonNull) {
4916 finalArgument = CGF.
Builder.CreateSelect(
4917 isNull, llvm::ConstantPointerNull::get(destType),
4923 originBB = CGF.
Builder.GetInsertBlock();
4926 CGF.
Builder.CreateCondBr(isNull, contBB, copyBB);
4928 condEval.
begin(CGF);
4932 llvm::Value *valueToUse =
nullptr;
4940 src = CGF.
Builder.CreateBitCast(src, destElemType,
"icr.cast");
4957 if (shouldCopy && !provablyNonNull) {
4958 llvm::BasicBlock *copyBB = CGF.
Builder.GetInsertBlock();
4963 llvm::PHINode *phiToUse =
4964 CGF.
Builder.CreatePHI(valueToUse->getType(), 2,
"icr.to-use");
4965 phiToUse->addIncoming(valueToUse, copyBB);
4966 phiToUse->addIncoming(llvm::PoisonValue::get(valueToUse->getType()),
4968 valueToUse = phiToUse;
4982 StackBase = CGF.
Builder.CreateStackSave(
"inalloca.save");
4988 CGF.
Builder.CreateStackRestore(StackBase);
4995 if (!AC.
getDecl() || !(
SanOpts.has(SanitizerKind::NonnullAttribute) ||
4996 SanOpts.has(SanitizerKind::NullabilityArg)))
5001 unsigned ArgNo = PVD ? PVD->getFunctionScopeIndex() : ParmNum;
5004 const NonNullAttr *NNAttr =
nullptr;
5005 if (
SanOpts.has(SanitizerKind::NonnullAttribute))
5008 bool CanCheckNullability =
false;
5009 if (
SanOpts.has(SanitizerKind::NullabilityArg) && !NNAttr && PVD &&
5010 !PVD->getType()->isRecordType()) {
5011 auto Nullability = PVD->getType()->getNullability();
5012 CanCheckNullability = Nullability &&
5014 PVD->getTypeSourceInfo();
5017 if (!NNAttr && !CanCheckNullability)
5024 AttrLoc = NNAttr->getLocation();
5025 CheckKind = SanitizerKind::SO_NonnullAttribute;
5026 Handler = SanitizerHandler::NonnullArg;
5028 AttrLoc = PVD->getTypeSourceInfo()->getTypeLoc().findNullabilityLoc();
5029 CheckKind = SanitizerKind::SO_NullabilityArg;
5030 Handler = SanitizerHandler::NullabilityArg;
5035 llvm::Constant *StaticData[] = {
5038 llvm::ConstantInt::get(
Int32Ty, ArgNo + 1),
5040 EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, {});
5046 if (!AC.
getDecl() || !(
SanOpts.has(SanitizerKind::NonnullAttribute) ||
5047 SanOpts.has(SanitizerKind::NullabilityArg)))
5066 return llvm::any_of(ArgTypes, [&](
QualType Ty) {
5077 return classDecl->getTypeParamListAsWritten();
5081 return catDecl->getTypeParamList();
5091 llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
5095 assert((ParamsToSkip == 0 ||
Prototype.P) &&
5096 "Can't skip parameters if type info is not provided");
5106 bool IsVariadic =
false;
5108 const auto *MD = dyn_cast<const ObjCMethodDecl *>(
Prototype.P);
5110 IsVariadic = MD->isVariadic();
5112 MD,
CGM.getTarget().getTriple().isOSWindows());
5113 ArgTypes.assign(MD->param_type_begin() + ParamsToSkip,
5114 MD->param_type_end());
5117 IsVariadic = FPT->isVariadic();
5118 ExplicitCC = FPT->getExtInfo().getCC();
5119 ArgTypes.assign(FPT->param_type_begin() + ParamsToSkip,
5120 FPT->param_type_end());
5128 assert(Arg != ArgRange.end() &&
"Running over edge of argument list!");
5130 QualType ArgTy = (*Arg)->getType();
5131 if (
const auto *OBT = ParamTy->
getAs<OverflowBehaviorType>())
5132 ParamTy = OBT->getUnderlyingType();
5133 if (
const auto *OBT = ArgTy->
getAs<OverflowBehaviorType>())
5134 ArgTy = OBT->getUnderlyingType();
5137 getContext().getCanonicalType(ParamTy).getTypePtr() ==
5138 getContext().getCanonicalType(ArgTy).getTypePtr()) &&
5139 "type mismatch in call argument!");
5145 assert((Arg == ArgRange.end() || IsVariadic) &&
5146 "Extra arguments in non-variadic function!");
5151 for (
auto *A : llvm::drop_begin(ArgRange, ArgTypes.size()))
5152 ArgTypes.push_back(IsVariadic ? getVarArgType(A) : A->getType());
5153 assert((
int)ArgTypes.size() == (ArgRange.end() - ArgRange.begin()));
5161 Order,
CGM.getTarget().getCXXABI());
5163 auto MaybeEmitImplicitObjectSize = [&](
unsigned I,
const Expr *Arg,
5172 auto SizeTy = Context.getSizeType();
5174 assert(EmittedArg.getScalarVal() &&
"We emitted nothing for the arg?");
5175 llvm::Value *
V = evaluateOrEmitBuiltinObjectSize(
5176 Arg, PS->getType(),
T, EmittedArg.getScalarVal(), PS->isDynamic());
5181 std::swap(Args.back(), *(&Args.back() - 1));
5187 "inalloca only supported on x86");
5192 size_t CallArgsStart = Args.size();
5193 for (
unsigned I = 0, E = ArgTypes.size(); I != E; ++I) {
5194 unsigned Idx = LeftToRight ? I : E - I - 1;
5196 unsigned InitialArgSize = Args.size();
5200 getContext().hasSameUnqualifiedType((*Arg)->getType(),
5204 "Argument and parameter types don't match");
5208 assert(InitialArgSize + 1 == Args.size() &&
5209 "The code below depends on only adding one arg per EmitCallArg");
5210 (void)InitialArgSize;
5213 if (!Args.back().hasLValue()) {
5214 RValue RVArg = Args.back().getKnownRValue();
5216 ParamsToSkip + Idx);
5220 MaybeEmitImplicitObjectSize(Idx, *Arg, RVArg);
5227 std::reverse(Args.begin() + CallArgsStart, Args.end());
5236struct DestroyUnpassedArg final : EHScopeStack::Cleanup {
5246 assert(!Dtor->isTrivial());
5269 if (!HasLV &&
RV.isScalar())
5271 else if (!HasLV &&
RV.isComplex())
5274 auto Addr = HasLV ?
LV.getAddress() :
RV.getAggregateAddress();
5278 HasLV ?
LV.isVolatileQualified()
5279 :
RV.isVolatileQualified());
5291 std::optional<DisableDebugLocationUpdates> Dis;
5295 dyn_cast<ObjCIndirectCopyRestoreExpr>(E)) {
5309 "reference binding to unmaterialized r-value!");
5321 if (
type->isRecordType() &&
5322 type->castAsRecordDecl()->isParamDestroyedInCallee()) {
5329 bool DestroyedInCallee =
true, NeedsCleanup =
true;
5330 if (
const auto *RD =
type->getAsCXXRecordDecl())
5331 DestroyedInCallee = RD->hasNonTrivialDestructor();
5333 NeedsCleanup =
type.isDestructedType();
5335 if (DestroyedInCallee)
5342 if (DestroyedInCallee && NeedsCleanup) {
5349 llvm::Instruction *IsActive =
5356 if (HasAggregateEvalKind) {
5357 auto *ICE = dyn_cast<ImplicitCastExpr>(E);
5358 if (ICE && ICE->getCastKind() == CK_LValueToRValue &&
5359 ICE->getSubExpr()->getType().getAddressSpace() !=
5361 !
type->isArrayParameterType() && !
type.isNonTrivialToPrimitiveCopy()) {
5372QualType CodeGenFunction::getVarArgType(
const Expr *Arg) {
5376 if (!getTarget().
getTriple().isOSWindows())
5380 getContext().getTypeSize(Arg->
getType()) <
5384 return getContext().getIntPtrType();
5392void CodeGenFunction::AddObjCARCExceptionMetadata(llvm::Instruction *Inst) {
5393 if (CGM.getCodeGenOpts().OptimizationLevel != 0 &&
5394 !CGM.getCodeGenOpts().ObjCAutoRefCountExceptions)
5395 Inst->setMetadata(
"clang.arc.no_objc_arc_exceptions",
5396 CGM.getNoObjCARCExceptionsMetadata());
5402 const llvm::Twine &name) {
5403 return EmitNounwindRuntimeCall(callee, ArrayRef<llvm::Value *>(), name);
5409 ArrayRef<Address> args,
5410 const llvm::Twine &name) {
5411 SmallVector<llvm::Value *, 3> values;
5412 for (
auto arg : args)
5413 values.push_back(
arg.emitRawPointer(*
this));
5414 return EmitNounwindRuntimeCall(callee, values, name);
5419 ArrayRef<llvm::Value *> args,
5420 const llvm::Twine &name) {
5421 llvm::CallInst *call = EmitRuntimeCall(callee, args, name);
5422 call->setDoesNotThrow();
5429 const llvm::Twine &name) {
5430 return EmitRuntimeCall(callee, {},
name);
5435SmallVector<llvm::OperandBundleDef, 1>
5444 if (
auto *CalleeFn = dyn_cast<llvm::Function>(Callee->stripPointerCasts())) {
5445 if (CalleeFn->isIntrinsic() && CalleeFn->doesNotThrow()) {
5446 auto IID = CalleeFn->getIntrinsicID();
5447 if (!llvm::IntrinsicInst::mayLowerToFunctionCall(IID))
5458 assert(F->isIntrinsic() &&
"expected an intrinsic declaration");
5459 return F->isConvergent();
5464 ArrayRef<llvm::Value *> args,
5465 const llvm::Twine &name,
5466 bool IsConvergent) {
5467 SmallVector<llvm::OperandBundleDef> BundleList =
5468 getBundlesForFunclet(callee.getCallee());
5470 addConvergenceControlBundle(BundleList);
5472 llvm::CallInst *call = Builder.CreateCall(callee, args, BundleList, name);
5473 call->setCallingConv(getRuntimeCC());
5474 assert((IsConvergent == call->isConvergent() ||
5475 (!IsConvergent && !CGM.shouldEmitConvergenceTokens())) &&
5476 "runtime call convergence doesn't match its declaration");
5481 const llvm::Twine &Name) {
5482 return EmitIntrinsicCall(ID, {}, {}, Name);
5486 ArrayRef<llvm::Value *> Args,
5487 const llvm::Twine &Name) {
5488 return EmitIntrinsicCall(ID, {}, Args, Name);
5492 ArrayRef<llvm::Type *> Types,
5493 ArrayRef<llvm::Value *> Args,
5494 const llvm::Twine &Name) {
5496 llvm::Intrinsic::getOrInsertDeclaration(&CGM.getModule(), ID, Types);
5497 SmallVector<llvm::OperandBundleDef> BundleList = getBundlesForFunclet(F);
5499 addConvergenceControlBundle(BundleList);
5500 return Builder.CreateCall(F, Args, BundleList, Name);
5504 ArrayRef<llvm::Value *> Args,
5506 const llvm::Twine &Name) {
5507 SmallVector<llvm::Type *> ArgTys;
5508 ArgTys.reserve(Args.size());
5509 for (llvm::Value *Arg : Args)
5510 ArgTys.push_back(Arg->
getType());
5511 llvm::Function *F = llvm::Intrinsic::getOrInsertDeclaration(
5512 &CGM.getModule(), ID, RetTy, ArgTys);
5513 SmallVector<llvm::OperandBundleDef> BundleList = getBundlesForFunclet(F);
5515 addConvergenceControlBundle(BundleList);
5516 return Builder.CreateCall(F, Args, BundleList, Name);
5526 llvm::InvokeInst *invoke =
Builder.CreateInvoke(
5528 invoke->setDoesNotReturn();
5531 llvm::CallInst *call =
Builder.CreateCall(callee, args, BundleList);
5532 call->setDoesNotReturn();
5541 const Twine &name) {
5549 const Twine &name) {
5559 const Twine &Name) {
5564 llvm::CallBase *Inst;
5566 Inst =
Builder.CreateCall(Callee, Args, BundleList, Name);
5569 Inst =
Builder.CreateInvoke(Callee, ContBB, InvokeDest, Args, BundleList,
5576 if (
CGM.getLangOpts().ObjCAutoRefCount)
5577 AddObjCARCExceptionMetadata(Inst);
5582void CodeGenFunction::deferPlaceholderReplacement(llvm::Instruction *Old,
5584 DeferredReplacements.push_back(
5585 std::make_pair(llvm::WeakTrackingVH(Old),
New));
5592[[nodiscard]] llvm::AttributeList
5593maybeRaiseRetAlignmentAttribute(llvm::LLVMContext &Ctx,
5594 const llvm::AttributeList &Attrs,
5595 llvm::Align NewAlign) {
5596 llvm::Align CurAlign = Attrs.getRetAlignment().valueOrOne();
5597 if (CurAlign >= NewAlign)
5599 llvm::Attribute AlignAttr = llvm::Attribute::getWithAlignment(Ctx, NewAlign);
5600 return Attrs.removeRetAttribute(Ctx, llvm::Attribute::AttrKind::Alignment)
5601 .addRetAttribute(Ctx, AlignAttr);
5604template <
typename AlignedAttrTy>
class AbstractAssumeAlignedAttrEmitter {
5609 const AlignedAttrTy *AA =
nullptr;
5611 llvm::Value *Alignment =
nullptr;
5612 llvm::ConstantInt *OffsetCI =
nullptr;
5618 AA = FuncDecl->
getAttr<AlignedAttrTy>();
5623 [[nodiscard]] llvm::AttributeList
5624 TryEmitAsCallSiteAttribute(
const llvm::AttributeList &Attrs) {
5625 if (!AA || OffsetCI || CGF.
SanOpts.
has(SanitizerKind::Alignment))
5627 const auto *AlignmentCI = dyn_cast<llvm::ConstantInt>(Alignment);
5632 if (!AlignmentCI->getValue().isPowerOf2())
5634 llvm::AttributeList NewAttrs = maybeRaiseRetAlignmentAttribute(
5637 AlignmentCI->getLimitedValue(llvm::Value::MaximumAlignment)));
5645 void EmitAsAnAssumption(SourceLocation Loc, QualType RetTy, RValue &Ret) {
5649 AA->getLocation(), Alignment, OffsetCI);
5655class AssumeAlignedAttrEmitter final
5656 :
public AbstractAssumeAlignedAttrEmitter<AssumeAlignedAttr> {
5658 AssumeAlignedAttrEmitter(CodeGenFunction &CGF_,
const Decl *FuncDecl)
5659 : AbstractAssumeAlignedAttrEmitter(CGF_, FuncDecl) {
5664 if (Expr *Offset = AA->getOffset()) {
5666 if (OffsetCI->isNullValue())
5673class AllocAlignAttrEmitter final
5674 :
public AbstractAssumeAlignedAttrEmitter<AllocAlignAttr> {
5676 AllocAlignAttrEmitter(CodeGenFunction &CGF_,
const Decl *FuncDecl,
5677 const CallArgList &CallArgs)
5678 : AbstractAssumeAlignedAttrEmitter(CGF_, FuncDecl) {
5682 Alignment = CallArgs[AA->getParamIndex().getLLVMIndex()]
5691 if (
auto *VT = dyn_cast<llvm::VectorType>(Ty))
5692 return VT->getPrimitiveSizeInBits().getKnownMinValue();
5693 if (
auto *AT = dyn_cast<llvm::ArrayType>(Ty))
5696 unsigned MaxVectorWidth = 0;
5697 if (
auto *ST = dyn_cast<llvm::StructType>(Ty))
5698 for (
auto *I : ST->elements())
5700 return MaxVectorWidth;
5707 llvm::CallBase **callOrInvoke,
bool IsMustTail,
5709 bool IsVirtualFunctionPointerThunk) {
5712 assert(Callee.isOrdinary() || Callee.isVirtual());
5719 llvm::FunctionType *IRFuncTy =
getTypes().GetFunctionType(CallInfo);
5721 const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl().getDecl();
5722 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
5729 if ((TargetDecl->
hasAttr<AlwaysInlineAttr>() &&
5730 (TargetDecl->
hasAttr<TargetAttr>() ||
5734 TargetDecl->
hasAttr<TargetAttr>())))
5741 const FunctionDecl *CalleeDecl = dyn_cast_or_null<FunctionDecl>(TargetDecl);
5742 CGM.getTargetCodeGenInfo().checkFunctionCallABI(
CGM, Loc, CallerDecl,
5743 CalleeDecl, CallArgs, RetTy);
5750 if (llvm::StructType *ArgStruct = CallInfo.
getArgStruct()) {
5751 const llvm::DataLayout &DL =
CGM.getDataLayout();
5753 llvm::AllocaInst *AI;
5755 IP = IP->getNextNode();
5756 AI =
new llvm::AllocaInst(ArgStruct, DL.getAllocaAddrSpace(),
"argmem",
5762 AI->setAlignment(Align.getAsAlign());
5763 AI->setUsedWithInAlloca(
true);
5764 assert(AI->isUsedWithInAlloca() && !AI->isStaticAlloca());
5765 ArgMemory =
RawAddress(AI, ArgStruct, Align);
5768 ClangToLLVMArgMapping IRFunctionArgs(
CGM.getContext(), CallInfo);
5776 bool NeedSRetLifetimeEnd =
false;
5782 if ((IsVirtualFunctionPointerThunk || IsMustTail) && RetAI.
isIndirect()) {
5784 IRFunctionArgs.getSRetArgNo(),
5792 if (NeedSRetLifetimeEnd)
5793 SRetAlloca = SRetPtr;
5796 if (IRFunctionArgs.hasSRetArg()) {
5809 IRCallArgs[IRFunctionArgs.getSRetArgNo()] =
5827 assert(CallInfo.
arg_size() == CallArgs.size() &&
5828 "Mismatch between function signature & arguments.");
5831 for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end();
5832 I != E; ++I, ++info_it, ++ArgNo) {
5836 if (IRFunctionArgs.hasPaddingArg(ArgNo))
5837 IRCallArgs[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
5840 unsigned FirstIRArg, NumIRArgs;
5841 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
5843 bool ArgHasMaybeUndefAttr =
5848 assert(NumIRArgs == 0);
5850 if (I->isAggregate()) {
5852 ? I->getKnownLValue().getAddress()
5853 : I->getKnownRValue().getAggregateAddress();
5854 llvm::Instruction *Placeholder =
5859 CGBuilderTy::InsertPoint IP =
Builder.saveIP();
5860 Builder.SetInsertPoint(Placeholder);
5874 deferPlaceholderReplacement(Placeholder,
Addr.getPointer());
5879 I->Ty,
getContext().getTypeAlignInChars(I->Ty),
5880 "indirect-arg-temp");
5881 I->copyInto(*
this,
Addr);
5890 I->copyInto(*
this,
Addr);
5897 assert(NumIRArgs == 1);
5898 if (I->isAggregate()) {
5908 ? I->getKnownLValue().getAddress()
5909 : I->getKnownRValue().getAggregateAddress();
5911 const llvm::DataLayout *TD = &
CGM.getDataLayout();
5913 assert((FirstIRArg >= IRFuncTy->getNumParams() ||
5914 IRFuncTy->getParamType(FirstIRArg)->getPointerAddressSpace() ==
5915 TD->getAllocaAddrSpace()) &&
5916 "indirect argument must be in alloca address space");
5918 bool NeedCopy =
false;
5919 if (
Addr.getAlignment() < Align &&
5920 llvm::getOrEnforceKnownAlignment(
Addr.emitRawPointer(*
this),
5924 }
else if (I->hasLValue()) {
5925 auto LV = I->getKnownLValue();
5930 if (!isByValOrRef ||
5931 (LV.getAlignment() <
getContext().getTypeAlignInChars(I->Ty))) {
5935 if (isByValOrRef &&
Addr.getType()->getAddressSpace() !=
5944 auto *
T = llvm::PointerType::get(
CGM.getLLVMContext(),
5952 if (ArgHasMaybeUndefAttr)
5953 Val =
Builder.CreateFreeze(Val);
5954 IRCallArgs[FirstIRArg] = Val;
5957 }
else if (I->getType()->isArrayParameterType()) {
5963 IRCallArgs[FirstIRArg] = I->getKnownRValue().getScalarVal();
5972 if (ArgHasMaybeUndefAttr)
5973 Val =
Builder.CreateFreeze(Val);
5974 IRCallArgs[FirstIRArg] = Val;
5979 CallLifetimeEndAfterCall.push_back(AI.
getPointer());
5982 I->copyInto(*
this, AI);
5987 assert(NumIRArgs == 0);
5995 assert(NumIRArgs == 1);
5997 if (!I->isAggregate())
5998 V = I->getKnownRValue().getScalarVal();
6001 I->hasLValue() ? I->getKnownLValue().getAddress()
6002 : I->getKnownRValue().getAggregateAddress());
6008 assert(!swiftErrorTemp.
isValid() &&
"multiple swifterror args");
6012 V, pointeeTy,
getContext().getTypeAlignInChars(pointeeTy));
6019 llvm::Value *errorValue =
Builder.CreateLoad(swiftErrorArg);
6020 Builder.CreateStore(errorValue, swiftErrorTemp);
6025 V->getType()->isIntegerTy())
6032 if (FirstIRArg < IRFuncTy->getNumParams() &&
6033 V->getType() != IRFuncTy->getParamType(FirstIRArg)) {
6034 assert(
V->getType()->isPointerTy() &&
"Only pointers can mismatch!");
6038 if (ArgHasMaybeUndefAttr)
6040 IRCallArgs[FirstIRArg] =
V;
6044 llvm::StructType *STy =
6049 if (!I->isAggregate()) {
6051 I->copyInto(*
this, Src);
6053 Src = I->hasLValue() ? I->getKnownLValue().getAddress()
6054 : I->getKnownRValue().getAggregateAddress();
6064 llvm::TypeSize SrcTypeSize =
6065 CGM.getDataLayout().getTypeAllocSize(SrcTy);
6066 llvm::TypeSize DstTypeSize =
CGM.getDataLayout().getTypeAllocSize(STy);
6067 if (SrcTypeSize.isScalable()) {
6068 assert(STy->containsHomogeneousScalableVectorTypes() &&
6069 "ABI only supports structure with homogeneous scalable vector "
6071 assert(SrcTypeSize == DstTypeSize &&
6072 "Only allow non-fractional movement of structure with "
6073 "homogeneous scalable vector type");
6074 assert(NumIRArgs == STy->getNumElements());
6076 llvm::Value *StoredStructValue =
6078 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
6079 llvm::Value *Extract =
Builder.CreateExtractValue(
6080 StoredStructValue, i, Src.
getName() +
".extract" + Twine(i));
6081 IRCallArgs[FirstIRArg + i] = Extract;
6084 uint64_t SrcSize = SrcTypeSize.getFixedValue();
6085 uint64_t DstSize = DstTypeSize.getFixedValue();
6086 bool HasPFPFields =
getContext().hasPFPFields(I->Ty);
6092 if (HasPFPFields || SrcSize < DstSize) {
6103 Builder.CreateMemCpy(TempAlloca, Src, SrcSize);
6109 assert(NumIRArgs == STy->getNumElements());
6110 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
6112 llvm::Value *LI =
Builder.CreateLoad(EltPtr);
6113 if (ArgHasMaybeUndefAttr)
6114 LI =
Builder.CreateFreeze(LI);
6115 IRCallArgs[FirstIRArg + i] = LI;
6120 assert(NumIRArgs == 1);
6128 auto *ATy = dyn_cast<llvm::ArrayType>(Load->getType());
6133 if (ArgHasMaybeUndefAttr)
6134 Load =
Builder.CreateFreeze(Load);
6135 IRCallArgs[FirstIRArg] = Load;
6143 auto layout =
CGM.getDataLayout().getStructLayout(coercionType);
6145 auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
6149 bool NeedLifetimeEnd =
false;
6150 if (I->isAggregate()) {
6151 addr = I->hasLValue() ? I->getKnownLValue().getAddress()
6152 : I->getKnownRValue().getAggregateAddress();
6155 RValue RV = I->getKnownRValue();
6159 auto scalarAlign =
CGM.getDataLayout().getPrefTypeAlign(scalarType);
6164 layout->getAlignment(), scalarAlign)),
6166 nullptr, &AllocaAddr);
6174 unsigned IRArgPos = FirstIRArg;
6175 unsigned unpaddedIndex = 0;
6176 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
6177 llvm::Type *eltType = coercionType->getElementType(i);
6184 : unpaddedCoercionType,
6186 if (ArgHasMaybeUndefAttr)
6187 elt =
Builder.CreateFreeze(elt);
6188 IRCallArgs[IRArgPos++] = elt;
6190 assert(IRArgPos == FirstIRArg + NumIRArgs);
6192 if (NeedLifetimeEnd)
6198 unsigned IRArgPos = FirstIRArg;
6199 ExpandTypeToArgs(I->Ty, *I, IRFuncTy, IRCallArgs, IRArgPos);
6200 assert(IRArgPos == FirstIRArg + NumIRArgs);
6206 if (!I->isAggregate()) {
6208 I->copyInto(*
this, Src);
6210 Src = I->hasLValue() ? I->getKnownLValue().getAddress()
6211 : I->getKnownRValue().getAggregateAddress();
6217 CGM.getABIInfo().createCoercedLoad(Src, ArgInfo, *
this);
6218 IRCallArgs[FirstIRArg] = Load;
6224 const CGCallee &ConcreteCallee = Callee.prepareConcreteCallee(*
this);
6230 assert(IRFunctionArgs.hasInallocaArg());
6231 IRCallArgs[IRFunctionArgs.getInallocaArgNo()] = Arg;
6242 auto simplifyVariadicCallee = [](llvm::FunctionType *CalleeFT,
6243 llvm::Value *Ptr) -> llvm::Function * {
6244 if (!CalleeFT->isVarArg())
6248 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Ptr)) {
6249 if (CE->getOpcode() == llvm::Instruction::BitCast)
6250 Ptr = CE->getOperand(0);
6253 llvm::Function *OrigFn = dyn_cast<llvm::Function>(Ptr);
6257 llvm::FunctionType *OrigFT = OrigFn->getFunctionType();
6261 if (OrigFT->isVarArg() ||
6262 OrigFT->getNumParams() != CalleeFT->getNumParams() ||
6263 OrigFT->getReturnType() != CalleeFT->getReturnType())
6266 for (
unsigned i = 0, e = OrigFT->getNumParams(); i != e; ++i)
6267 if (OrigFT->getParamType(i) != CalleeFT->getParamType(i))
6273 if (llvm::Function *OrigFn = simplifyVariadicCallee(IRFuncTy, CalleePtr)) {
6275 IRFuncTy = OrigFn->getFunctionType();
6286 for (
unsigned i = 0; i < IRCallArgs.size(); ++i)
6287 LargestVectorWidth = std::max(LargestVectorWidth,
6292 llvm::AttributeList Attrs;
6293 CGM.ConstructAttributeList(CalleePtr->getName(), CallInfo,
6298 if (
CallingConv == llvm::CallingConv::X86_VectorCall &&
6300 CGM.Error(Loc,
"__vectorcall calling convention is not currently "
6305 if (FD->hasAttr<StrictFPAttr>())
6307 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::StrictFP);
6312 if (FD->hasAttr<OptimizeNoneAttr>() &&
getLangOpts().FastMath)
6313 CGM.AdjustMemoryAttribute(CalleePtr->getName(), Callee.getAbstractInfo(),
6318 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::NoMerge);
6322 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::NoInline);
6327 !
CGM.getTargetCodeGenInfo().wouldInliningViolateFunctionCallABI(
6328 CallerDecl, CalleeDecl))
6330 Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::AlwaysInline);
6339 !(TargetDecl && TargetDecl->
hasAttr<NoInlineAttr>()) &&
6340 !
CGM.getTargetCodeGenInfo().wouldInliningViolateFunctionCallABI(
6341 CallerDecl, CalleeDecl)) {
6343 Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::AlwaysInline);
6348 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::NoInline);
6355 CannotThrow =
false;
6364 CannotThrow = Attrs.hasFnAttr(llvm::Attribute::NoUnwind);
6366 if (
auto *FPtr = dyn_cast<llvm::Function>(CalleePtr))
6367 if (FPtr->hasFnAttribute(llvm::Attribute::NoUnwind))
6378 if (NeedSRetLifetimeEnd)
6386 if (
SanOpts.has(SanitizerKind::KCFI) &&
6387 !isa_and_nonnull<FunctionDecl>(TargetDecl))
6394 if (FD->hasAttr<StrictFPAttr>())
6396 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::StrictFP);
6398 AssumeAlignedAttrEmitter AssumeAlignedAttrEmitter(*
this, TargetDecl);
6399 Attrs = AssumeAlignedAttrEmitter.TryEmitAsCallSiteAttribute(Attrs);
6401 AllocAlignAttrEmitter AllocAlignAttrEmitter(*
this, TargetDecl, CallArgs);
6402 Attrs = AllocAlignAttrEmitter.TryEmitAsCallSiteAttribute(Attrs);
6404 if (Attrs.hasFnAttr(llvm::Attribute::Convergent)) {
6405 addConvergenceControlBundle(BundleList);
6415 auto *CalleeFn = dyn_cast<llvm::Function>(CalleePtr);
6417 (!
CGM.shouldEmitConvergenceTokens() ||
6418 (CalleeFn && CalleeFn->isConvergent()))) {
6420 llvm::Attribute::Convergent);
6427 CI =
Builder.CreateCall(IRFuncTy, CalleePtr, IRCallArgs, BundleList);
6430 CI =
Builder.CreateInvoke(IRFuncTy, CalleePtr, Cont, InvokeDest, IRCallArgs,
6434 if (CI->getCalledFunction() && CI->getCalledFunction()->hasName() &&
6435 CI->getCalledFunction()->getName().starts_with(
"_Z4sqrt")) {
6440 if (
CGM.getCodeGenOpts().CallGraphSection) {
6444 else if (
const auto *FPT =
6445 Callee.getAbstractInfo().getCalleeFunctionProtoType())
6447 else if (
const auto *FT =
6448 Callee.getAbstractInfo().getCalleeFunctionType())
6452 "Cannot find the callee type to generate callee_type metadata.");
6495 for (
const CallArg &Arg : CallArgs)
6496 ParamTypes.push_back(Arg.
getType());
6497 CST =
CGM.ReconstructCallGraphPrototype(FNPT, ParamTypes);
6500 llvm::Metadata *MD =
6501 CGM.CreateMetadataIdentifierForCallGraphType(CST);
6503 if (
auto *MDS = dyn_cast_or_null<llvm::MDString>(MD))
6504 TypeStr = MDS->getString();
6506 CGM.getDiags().Report(Loc, diag::warn_cgs_no_proto) << CST << TypeStr;
6508 CGM.createCalleeTypeMetadataForIcall(CST, *callOrInvoke);
6516 if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(
CurFuncDecl)) {
6517 if (
const auto *A = FD->getAttr<CFGuardAttr>()) {
6518 if (A->getGuard() == CFGuardAttr::GuardArg::nocf &&
6519 !CI->getCalledFunction())
6525 CI->setAttributes(Attrs);
6526 CI->setCallingConv(
static_cast<llvm::CallingConv::ID
>(
CallingConv));
6530 if (!CI->getType()->isVoidTy())
6531 CI->setName(
"call");
6534 LargestVectorWidth =
6540 if (!CI->getCalledFunction())
6541 PGO->valueProfile(
Builder, llvm::IPVK_IndirectCallTarget, CI, CalleePtr);
6545 if (
CGM.getLangOpts().ObjCAutoRefCount)
6546 AddObjCARCExceptionMetadata(CI);
6549 bool IsPPC =
getTarget().getTriple().isPPC();
6550 bool IsMIPS =
getTarget().getTriple().isMIPS();
6551 bool HasMips16 =
false;
6554 HasMips16 = TargetOpts.
FeatureMap.lookup(
"mips16");
6556 HasMips16 = llvm::is_contained(TargetOpts.
Features,
"+mips16");
6558 if (llvm::CallInst *
Call = dyn_cast<llvm::CallInst>(CI)) {
6559 if (TargetDecl && TargetDecl->
hasAttr<NotTailCalledAttr>())
6560 Call->setTailCallKind(llvm::CallInst::TCK_NoTail);
6561 else if (IsMustTail) {
6564 CGM.getDiags().Report(Loc, diag::err_aix_musttail_unsupported);
6567 CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail) << 0;
6568 else if (
Call->isIndirectCall())
6569 CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail) << 1;
6570 else if (isa_and_nonnull<FunctionDecl>(TargetDecl)) {
6575 CGM.addUndefinedGlobalForTailCall(
6578 llvm::GlobalValue::LinkageTypes
Linkage =
CGM.getFunctionLinkage(
6580 if (llvm::GlobalValue::isWeakForLinker(
Linkage) ||
6581 llvm::GlobalValue::isDiscardableIfUnused(
Linkage))
6582 CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail)
6590 CGM.getDiags().Report(Loc, diag::err_mips_impossible_musttail) << 0;
6591 else if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
6592 CGM.addUndefinedGlobalForTailCall({FD, Loc});
6594 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
6608 bool NeedSrcLoc = TargetDecl->
hasAttr<ErrorAttr>();
6609 if (!NeedSrcLoc &&
CGM.getCodeGenOpts().ShowInliningChain) {
6610 if (
const auto *FD = dyn_cast<FunctionDecl>(TargetDecl))
6611 NeedSrcLoc = FD->isInlined() || FD->hasAttr<AlwaysInlineAttr>() ||
6613 FD->isInAnonymousNamespace();
6617 auto *MD = llvm::ConstantAsMetadata::get(
Line);
6618 CI->setMetadata(
"srcloc", llvm::MDNode::get(
getLLVMContext(), {MD}));
6627 if (CI->doesNotReturn()) {
6628 if (NeedSRetLifetimeEnd)
6632 if (
SanOpts.has(SanitizerKind::Unreachable)) {
6635 if (
auto *F = CI->getCalledFunction())
6636 F->removeFnAttr(llvm::Attribute::NoReturn);
6637 CI->removeFnAttr(llvm::Attribute::NoReturn);
6641 if (
SanOpts.hasOneOf(SanitizerKind::Address |
6642 SanitizerKind::KernelAddress)) {
6644 llvm::IRBuilder<>::InsertPointGuard IPGuard(
Builder);
6646 auto *FnType = llvm::FunctionType::get(
CGM.VoidTy,
false);
6647 llvm::FunctionCallee Fn =
6648 CGM.CreateRuntimeFunction(FnType,
"__asan_handle_no_return");
6654 Builder.ClearInsertionPoint();
6676 if (CI->doesNotThrow())
6679 diag::err_musttail_noexcept_mismatch);
6682 if (
auto *Cleanup = dyn_cast<EHCleanupScope>(&*it)) {
6685 if (Cleanup->isFakeUse()) {
6686 CGBuilderTy::InsertPointGuard IPG(
Builder);
6688 Cleanup->getCleanup()->Emit(*
this, EHScopeStack::Cleanup::Flags());
6691 if (Cleanup->isRedundantBeforeReturn())
6694 CGM.ErrorUnsupported(
MustTailCall,
"tail call skipping over cleanups");
6696 if (CI->getType()->isVoidTy())
6700 Builder.ClearInsertionPoint();
6706 if (swiftErrorTemp.
isValid()) {
6707 llvm::Value *errorResult =
Builder.CreateLoad(swiftErrorTemp);
6708 Builder.CreateStore(errorResult, swiftErrorArg);
6725 if (IsVirtualFunctionPointerThunk) {
6738 unsigned unpaddedIndex = 0;
6739 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
6740 llvm::Type *eltType = coercionType->getElementType(i);
6744 llvm::Value *elt = CI;
6745 if (requiresExtract)
6746 elt =
Builder.CreateExtractValue(elt, unpaddedIndex++);
6748 assert(unpaddedIndex == 0);
6749 Builder.CreateStore(elt, eltAddr);
6757 if (NeedSRetLifetimeEnd)
6774 llvm::Value *Real =
Builder.CreateExtractValue(CI, 0);
6775 llvm::Value *Imag =
Builder.CreateExtractValue(CI, 1);
6783 llvm::Value *
V = CI;
6784 if (
V->getType() != RetIRTy)
6794 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(RetIRTy)) {
6795 llvm::Value *
V = CI;
6796 if (
auto *ScalableSrcTy =
6797 dyn_cast<llvm::ScalableVectorType>(
V->getType())) {
6798 if (FixedDstTy->getElementType() ==
6799 ScalableSrcTy->getElementType()) {
6800 V =
Builder.CreateExtractVector(FixedDstTy,
V, uint64_t(0),
6810 getContext().getTypeInfoDataSizeInChars(RetTy).Width.getQuantity();
6814 DestIsVolatile =
false;
6815 DestSize =
getContext().getTypeSizeInChars(RetTy).getQuantity();
6825 CI, RetTy, StorePtr,
6839 DestIsVolatile =
false;
6841 CGM.getABIInfo().createCoercedStore(CI, StorePtr, RetAI, DestIsVolatile,
6848 llvm_unreachable(
"Invalid ABI kind for return argument");
6851 llvm_unreachable(
"Unhandled ABIArgInfo::Kind");
6856 if (Ret.isScalar() && TargetDecl) {
6857 AssumeAlignedAttrEmitter.EmitAsAnAssumption(Loc, RetTy, Ret);
6858 AllocAlignAttrEmitter.EmitAsAnAssumption(Loc, RetTy, Ret);
6863 for (llvm::Value *LifetimeEndAddr : CallLifetimeEndAfterCall)
6876 if (CalleeDecl && !CalleeDecl->
hasAttr<NoDebugAttr>() &&
6877 DI->getCallSiteRelatedAttrs() != llvm::DINode::FlagZero) {
6878 CodeGenFunction CalleeCGF(
CGM);
6880 Callee.getAbstractInfo().getCalleeDecl();
6881 CalleeCGF.
CurGD = CalleeGlobalDecl;
6884 DI->EmitFuncDeclForCallSite(
6885 CI, DI->getFunctionType(CalleeDecl, ResTy, Args), CalleeGlobalDecl);
6888 DI->addCallTargetIfVirtual(CalleeDecl, CI);
6909 VAListAddr =
VE->isMicrosoftABI()
6916 if (
VE->isMicrosoftABI())
6917 return CGM.getABIInfo().EmitMSVAArg(*
this, VAListAddr, Ty, Slot);
6919 return CGM.getABIInfo().EmitZOSVAArg(*
this, VAListAddr, Ty, Slot);
6920 return CGM.getABIInfo().EmitVAArg(*
this, VAListAddr, Ty, Slot);
6925 CGF.disableDebugInfo();
6929 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 const char * abiKindToString(ABIArgInfo::Kind K)
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 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 * CreatePFPCoercedLoad(Address Src, QualType SrcFETy, llvm::Type *Ty, CodeGenFunction &CGF)
static int getExpansionSize(QualType Ty, const ASTContext &Context)
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 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 bool isConvergentIntrinsic(const llvm::Function *F)
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 llvm::Value * CreateCoercedLoad(Address Src, QualType SrcFETy, llvm::Type *Ty, CodeGenFunction &CGF)
CreateCoercedLoad - Create a load from.
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 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 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 bool CreatePFPCoercedStore(llvm::Value *Src, QualType SrcFETy, Address Dst, CodeGenFunction &CGF)
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 std::optional< ArgClassification > convertABIArgInfo(const llvm::abi::ArgInfo &info, MLIRContext *ctx, mlir::Type origTy)
Convert an llvm::abi::ArgInfo into the ArgClassification consumed by CIRABIRewriteContext.
static void setCUDAKernelCallingConvention(CanQualType &funcTy, CIRGenModule &cgm, const FunctionDecl *fd)
Set calling convention for CUDA/HIP kernel.
static void addNoBuiltinAttributes(mlir::MLIRContext &ctx, mlir::NamedAttrList &attrs, const LangOptions &langOpts, const NoBuiltinAttr *nba=nullptr)
static void addDenormalModeAttrs(llvm::DenormalMode fpDenormalMode, llvm::DenormalMode fp32DenormalMode, mlir::NamedAttrList &attrs)
Add denormal-fp-math and denormal-fp-math-f32 as appropriate for the requested denormal behavior,...
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....
Result
Implement __builtin_bit_cast and related operations.
#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 StringRef getTriple(const Command &Job)
Maps Clang QualType instances to corresponding LLVM ABI type representations.
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
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
std::vector< PFPField > findPFPFields(QualType Ty) const
Returns a list of PFP fields for the given type, including subfields in bases or other fields,...
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.
This is an opaque type for sizes expressed in character units.
bool isZero() const
Test whether the quantity equals zero.
llvm::Align getAsAlign() const
Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit bytes.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
static CharUnits 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 ...
static ABIArgInfo getZeroExtend(QualType Ty, llvm::Type *T=nullptr, llvm::Type *Padding=nullptr)
unsigned getInAllocaFieldIndex() const
static ABIArgInfo getSignExtend(QualType Ty, llvm::Type *T=nullptr, llvm::Type *Padding=nullptr)
bool getIndirectByVal() const
llvm::StructType * getCoerceAndExpandType() const
bool getIndirectRealign() const
static ABIArgInfo getIgnore()
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
static ABIArgInfo getDirect(llvm::Type *T=nullptr, unsigned Offset=0, llvm::Type *Padding=nullptr, bool CanBeFlattened=true, unsigned Align=0)
@ 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...
static ABIArgInfo getExtend(QualType Ty, llvm::Type *T=nullptr, llvm::Type *Padding=nullptr)
static ABIArgInfo getIndirect(CharUnits Alignment, unsigned AddrSpace, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
ArrayRef< llvm::Type * > getCoerceAndExpandTypeSequence() const
static ABIArgInfo getIndirectAliased(CharUnits Alignment, unsigned AddrSpace, bool Realign=false, llvm::Type *Padding=nullptr)
Pass this in memory using the IR byref attribute.
bool isCoerceAndExpand() const
static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType, llvm::Type *unpaddedCoerceToType)
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.
unsigned getCallingConvention() const
getCallingConvention - Return the user specified calling convention, which has been translated into a...
void Profile(llvm::FoldingSetNodeID &ID)
const_arg_iterator arg_begin() const
ArrayRef< ExtParameterInfo > getExtParameterInfos() const
CanQualType getReturnType() const
static CGFunctionInfo * create(unsigned llvmCC, bool instanceMethod, bool chainCall, bool delegateCall, unsigned X86ABIAVXLevel, const FunctionType::ExtInfo &extInfo, ArrayRef< ExtParameterInfo > paramInfos, CanQualType resultType, ArrayRef< CanQualType > argTypes, RequiredArgs required)
const ArgInfo * const_arg_iterator
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 ...
unsigned getX86ABIAVXLevel() const
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...
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.
llvm::Value * performAddrSpaceCast(llvm::Value *Src, llvm::Type *DestTy)
SanitizerSet SanOpts
Sanitizers enabled for this function.
CodeGenUtils::EvaluationOrder EvaluationOrder
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.
void CreateCoercedStore(llvm::Value *Src, QualType SrcFETy, Address Dst, llvm::TypeSize DstSize, bool DstIsVolatile)
Create a store to.
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
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.
llvm::CallInst * EmitIntrinsicCall(llvm::Intrinsic::ID ID, const Twine &Name="")
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,...
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...
LValue EmitHLSLOutArgExpr(const HLSLOutArgExpr *E, CallArgList &Args, QualType Ty, bool IsImplicitObject=false)
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.
Address EmitAddressOfPFPField(Address RecordPtr, const PFPField &Field)
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)
Address EmitZOSVAListRef(const Expr *E)
Emit a "reference" to a __builtin_zos_va_list; this is always the address of the expression,...
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...
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.
const ABIInfo & getABIInfo()
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
void computeABIInfoUsingLib(CGFunctionInfo &FI)
Drive the experimental LLVMABI-based lowering path: map argument and return types into the LLVMABI li...
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.
const llvm::abi::TargetInfo & getLLVMABITargetInfo(llvm::abi::TypeBuilder &TB)
Lazily build and return the LLVMABI library's TargetInfo for the current target.
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 & arrangeLLVMFunctionInfo(CanQualType returnType, FnInfoOpts opts, ArrayRef< CanQualType > argTypes, FunctionType::ExtInfo info, ArrayRef< FunctionProtoType::ExtParameterInfo > paramInfos, RequiredArgs args, const FunctionDecl *ABIInfoFD)
"Arrange" the LLVM information for a call or type with the given signature.
const CGFunctionInfo & arrangeFreeFunctionCall(const CallArgList &Args, const FunctionType *Ty, bool ChainCall, const FunctionDecl *ABIInfoFD)
Figure out the rules for calling a function with the given formal type using the given arguments.
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...
const CGFunctionInfo & arrangeCXXConstructorCall(const CallArgList &Args, const CXXConstructorDecl *D, CXXCtorType CtorKind, unsigned ExtraPrefixArgs, unsigned ExtraSuffixArgs, const FunctionDecl *ABIInfoFD, bool PassProtoArgs=true)
Arrange a call to a C++ method, passing the given arguments.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
CGCXXABI & getCXXABI() const
const CGFunctionInfo & arrangeCXXMethodCall(const CallArgList &args, const FunctionProtoType *type, RequiredArgs required, unsigned numPrefixArgs, const FunctionDecl *ABIInfoFD)
Arrange a call to a C++ method, passing the given arguments.
const CGFunctionInfo & arrangeCXXMethodDeclaration(const CXXMethodDecl *MD)
C++ methods have some special rules and also have implicit parameters.
ASTContext & getContext() const
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 & 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 & arrangeCall(const CGFunctionInfo &declFI, const CallArgList &args, const FunctionDecl *ABIInfoFD)
Given a function info for a declaration, return the function info for a call with 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 & arrangeNullaryFunction()
A nullary function is a freestanding function of type 'void ()'.
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.
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
ExtInfo withProducesResult(bool producesResult) 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
CXXDtorType getDtorType() 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.
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
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
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.
llvm::StringMap< bool > FeatureMap
The map of which features have been enabled disabled based on the command line.
The base class of the type hierarchy.
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 isFunctionProtoType() 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.
CanQual< FunctionProtoType > getFormalType(const CXXMethodDecl *MD)
Returns the canonical formal type of the given C++ method.
llvm::FPClassTest getNoFPClassTestMask(const LangOptions &LangOpts)
Returns the set of floating-point value kinds that the language options promise never reach a functio...
bool shouldEvaluateArgsLeftToRight(EvaluationOrder Order, const TargetCXXABI &ABI)
Returns true if call arguments should be emitted left-to-right, given the order the language requires...
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)
const EHPersonality & getEHPersonality(CodeGenModule &CGM, const FunctionDecl *FD)
Selects the personality function to use for FD, or for the translation unit as a whole when FD is nul...
@ 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...
QualType useFirstFieldIfTransparentUnion(QualType Ty)
Pass transparent unions as if they were the type of the first element.
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.
PRESERVE_NONE bool Ret(InterpState &S)
bool This(InterpState &S, CodePtr OpPC)
@ Address
A pointer to a ValueDecl.
Top level wrappers for InstallAPI frontend operations.
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)
static bool classof(const OMPClause *T)
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',...
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_VectorDeleting
Vector deleting dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
@ 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)
@ Struct
The "struct" keyword introduces the elaborated-type-specifier.
__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)
bool isMSVCXXPersonality() const
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, not including padding.
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::PointerType * VoidPtrTy
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)
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.