36#include "llvm/ABI/FunctionInfo.h"
37#include "llvm/ABI/IRTypeMapper.h"
38#include "llvm/ABI/TargetInfo.h"
39#include "llvm/ABI/Types.h"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/StringExtras.h"
42#include "llvm/Analysis/ValueTracking.h"
43#include "llvm/IR/Assumptions.h"
44#include "llvm/IR/AttributeMask.h"
45#include "llvm/IR/Attributes.h"
46#include "llvm/IR/CallingConv.h"
47#include "llvm/IR/DataLayout.h"
48#include "llvm/IR/DebugInfoMetadata.h"
49#include "llvm/IR/InlineAsm.h"
50#include "llvm/IR/IntrinsicInst.h"
51#include "llvm/IR/Intrinsics.h"
52#include "llvm/IR/Type.h"
53#include "llvm/Transforms/Utils/Local.h"
63 return llvm::CallingConv::C;
65 return llvm::CallingConv::X86_StdCall;
67 return llvm::CallingConv::X86_FastCall;
69 return llvm::CallingConv::X86_RegCall;
71 return llvm::CallingConv::X86_ThisCall;
73 return llvm::CallingConv::Win64;
75 return llvm::CallingConv::X86_64_SysV;
77 return llvm::CallingConv::ARM_AAPCS;
79 return llvm::CallingConv::ARM_AAPCS_VFP;
81 return llvm::CallingConv::Intel_OCL_BI;
84 return llvm::CallingConv::C;
87 return llvm::CallingConv::X86_VectorCall;
89 return llvm::CallingConv::AArch64_VectorCall;
91 return llvm::CallingConv::AArch64_SVE_VectorCall;
93 return llvm::CallingConv::SPIR_FUNC;
95 return CGM.getTargetCodeGenInfo().getDeviceKernelCallingConv();
97 return llvm::CallingConv::PreserveMost;
99 return llvm::CallingConv::PreserveAll;
101 return llvm::CallingConv::Swift;
103 return llvm::CallingConv::SwiftTail;
105 return llvm::CallingConv::M68k_RTD;
107 return llvm::CallingConv::PreserveNone;
111#define CC_VLS_CASE(ABI_VLEN) \
112 case CC_RISCVVLSCall_##ABI_VLEN: \
113 return llvm::CallingConv::RISCV_VLSCall_##ABI_VLEN;
138 RecTy = Context.getCanonicalTagType(RD);
140 RecTy = Context.VoidTy;
145 return Context.getPointerType(RecTy);
178 assert(paramInfos.size() <= prefixArgs);
179 assert(proto->
getNumParams() + prefixArgs <= totalArgs);
181 paramInfos.reserve(totalArgs);
184 paramInfos.resize(prefixArgs);
188 paramInfos.push_back(ParamInfo);
190 if (ParamInfo.hasPassObjectSize())
191 paramInfos.emplace_back();
194 assert(paramInfos.size() <= totalArgs &&
195 "Did we forget to insert pass_object_size args?");
197 paramInfos.resize(totalArgs);
207 if (!FPT->hasExtParameterInfos()) {
208 assert(paramInfos.empty() &&
209 "We have paramInfos, but the prototype doesn't?");
210 prefix.append(FPT->param_type_begin(), FPT->param_type_end());
214 unsigned PrefixSize = prefix.size();
218 prefix.reserve(prefix.size() + FPT->getNumParams());
220 auto ExtInfos = FPT->getExtParameterInfos();
221 assert(ExtInfos.size() == FPT->getNumParams());
222 for (
unsigned I = 0, E = FPT->getNumParams(); I != E; ++I) {
223 prefix.push_back(FPT->getParamType(I));
224 if (ExtInfos[I].hasPassObjectSize())
249 FTP->getExtInfo(), paramInfos,
Required,
260 return ::arrangeLLVMFunctionInfo(*
this,
false, argTypes,
265 bool IsTargetDefaultMSABI) {
270 if (D->
hasAttr<FastCallAttr>())
276 if (D->
hasAttr<ThisCallAttr>())
279 if (D->
hasAttr<VectorCallAttr>())
285 if (PcsAttr *PCS = D->
getAttr<PcsAttr>())
288 if (D->
hasAttr<AArch64VectorPcsAttr>())
291 if (D->
hasAttr<AArch64SVEPcsAttr>())
294 if (D->
hasAttr<DeviceKernelAttr>())
297 if (D->
hasAttr<IntelOclBiccAttr>())
306 if (D->
hasAttr<PreserveMostAttr>())
309 if (D->
hasAttr<PreserveAllAttr>())
315 if (D->
hasAttr<PreserveNoneAttr>())
318 if (D->
hasAttr<RISCVVectorCCAttr>())
321 if (RISCVVLSCCAttr *PCS = D->
getAttr<RISCVVLSCCAttr>()) {
322 switch (PCS->getVectorWidth()) {
324 llvm_unreachable(
"Invalid RISC-V VLS ABI VLEN");
325#define CC_VLS_CASE(ABI_VLEN) \
327 return CC_RISCVVLSCall_##ABI_VLEN;
365 CanonicalFTP.getTypePtr(), argTypes.size());
368 CanonicalFTP->getReturnType().getUnqualifiedType(),
370 paramInfos, required, MD);
376 if (FD->
hasAttr<CUDAGlobalAttr>()) {
408 argTypes, prototype->getExtInfo(), paramInfos,
418 !Target.getCXXABI().hasConstructorVariants();
431 bool PassParams =
true;
433 if (
auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
436 if (
auto Inherited = CD->getInheritedConstructor())
448 if (!paramInfos.empty()) {
451 paramInfos.insert(paramInfos.begin() + 1, AddedArgs.
Prefix,
454 paramInfos.append(AddedArgs.
Suffix,
459 (PassParams && MD->isVariadic() ?
RequiredArgs(argTypes.size())
465 ? CGM.getContext().VoidPtrTy
468 argTypes, extInfo, paramInfos, required, MD);
474 for (
auto &arg : args)
482 for (
auto &arg : args)
489 unsigned totalArgs) {
507 unsigned ExtraPrefixArgs,
unsigned ExtraSuffixArgs,
510 for (
const auto &Arg : args)
511 ArgTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
514 unsigned TotalPrefixArgs = 1 + ExtraPrefixArgs;
519 FPT, TotalPrefixArgs + ExtraSuffixArgs)
525 ? CGM.getContext().VoidPtrTy
532 if (PassProtoArgs && FPT->hasExtParameterInfos()) {
539 ArgTypes, Info, ParamInfos,
Required,
549 if (MD->isImplicitObjectMemberFunction())
557 if (DeviceKernelAttr::isOpenCLSpelling(FD->
getAttr<DeviceKernelAttr>()) &&
560 CGM.getTargetCodeGenInfo().setOCLKernelStubCallingConvention(FT);
568 {}, noProto->getExtInfo(), {},
602 argTys.push_back(Context.getCanonicalParamType(receiverType));
604 argTys.push_back(Context.getCanonicalParamType(Context.getObjCSelType()));
606 argTys.push_back(Context.getCanonicalParamType(I->getType()));
608 I->hasAttr<NoEscapeAttr>());
609 extParamInfos.push_back(extParamInfo);
613 bool IsTargetDefaultMSABI =
619 if (
getContext().getLangOpts().ObjCAutoRefCount &&
620 MD->
hasAttr<NSReturnsRetainedAttr>())
658 assert(MD->
isVirtual() &&
"only methods have thunks");
675 ArgTys.push_back(*FTP->param_type_begin());
677 ArgTys.push_back(Context.IntTy);
678 CallingConv CC = Context.getDefaultCallingConvention(
690 unsigned numExtraRequiredArgs,
bool chainCall,
692 assert(args.size() >= numExtraRequiredArgs);
702 if (proto->isVariadic())
705 if (proto->hasExtParameterInfos())
719 for (
const auto &arg : args)
724 paramInfos, required, ABIInfoFD);
735 chainCall ? 1 : 0, chainCall, ABIInfoFD);
767 for (
const auto &Arg : args)
768 argTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
810 assert(numPrefixArgs + 1 <= args.size() &&
811 "Emitting a call with less args than the required prefix?");
822 paramInfos, required, ABIInfoFD);
834 assert(signature.
arg_size() <= args.size());
835 unsigned X86ABIAVXLevel =
836 CGM.getABIInfo().getX86ABIAVXLevel(ABIInfoFD, signature.
getExtInfo());
837 if (signature.
arg_size() == args.size() &&
843 if (!sigParamInfos.empty()) {
844 paramInfos.append(sigParamInfos.begin(), sigParamInfos.end());
845 paramInfos.resize(args.size());
883 return "IndirectAliased";
889 return "CoerceAndExpand";
891 return "TargetSpecific";
895 llvm_unreachable(
"Unknown kind");
901 MappedArgTypes.reserve(FI.
arg_size());
903 MappedArgTypes.push_back(AbiMapper->convertType(Arg.type));
905 std::optional<unsigned> NumRequired;
908 NumRequired =
Required.getNumRequiredArgs();
910 auto AbiFI = llvm::abi::FunctionInfo::create(
912 MappedArgTypes, NumRequired);
921 auto ConvertABIArgInfo = [&](
ABIArgInfo &Target,
924 auto Check = [&](
bool Cond, llvm::function_ref<void()> MessageFn) {
928 llvm::dbgs() <<
"For return value of type ";
930 llvm::dbgs() <<
"For argument " << ArgNo <<
" of type ";
931 llvm::dbgs() <<
Type <<
": ";
933 llvm::dbgs() <<
"\n";
936 auto CheckSimple = [&](
auto TargetVal,
auto ResVal, StringRef What) {
937 Check(TargetVal == ResVal, [&]() {
938 llvm::dbgs() << What <<
" mismatch (expected: " << TargetVal
939 <<
", given: " << ResVal <<
")";
944 Check(Target.getKind() == Res.
getKind(), [&]() {
945 llvm::dbgs() <<
"Kind mismatch (expected: "
946 << abiKindToString(Target.getKind())
947 <<
", given: " << abiKindToString(Res.getKind()) <<
")";
952 llvm::Type *TargetType = Target.getCoerceToType();
959 Check(TargetType == ResType, [&]() {
960 llvm::dbgs() <<
"CoerceToType mismatch (expected: " << *TargetType
961 <<
", given: " << *ResType <<
")";
967 CheckSimple(Target.isSignExt(), Res.
isSignExt(),
"SignExt");
968 CheckSimple(Target.isZeroExt(), Res.
isZeroExt(),
"ZeroExt");
971 CheckSimple(Target.getDirectAlign(), Res.
getDirectAlign(),
"DirectAlign");
981 "IndirectAddrSpace");
985 llvm::dbgs() <<
"IndirectAlign mismatch (expected: "
986 << Target.getIndirectAlign().getQuantity()
987 <<
", given: " << Res.getIndirectAlign().getQuantity()
998 auto ConvertABIArgInfo =
1000 int ArgNo) { Target = convertABIArgInfo(AbiInfo,
Type); };
1003 ConvertABIArgInfo(FI.
getReturnInfo(), AbiFI->getReturnInfo(),
1007 for (
auto [CGArg, AbiArg] :
1008 llvm::zip_equal(FI.
arguments(), AbiFI->arguments()))
1009 ConvertABIArgInfo(CGArg.info, AbiArg.Info, CGArg.type, ArgNo++);
1012ABIArgInfo CodeGenModule::convertABIArgInfo(
const llvm::abi::ArgInfo &AbiInfo,
1014 switch (AbiInfo.getKind()) {
1015 case llvm::abi::ArgInfo::Direct: {
1016 llvm::Type *CoercedType =
nullptr;
1017 if (AbiInfo.getCoerceToType())
1018 CoercedType = AbiReverseMapper->convertType(AbiInfo.getCoerceToType());
1020 CoercedType = getTypes().ConvertType(
Type);
1023 case llvm::abi::ArgInfo::Extend: {
1024 llvm::Type *CoercedType =
nullptr;
1025 if (AbiInfo.getCoerceToType())
1026 CoercedType = AbiReverseMapper->convertType(AbiInfo.getCoerceToType());
1028 CoercedType = getTypes().ConvertType(
Type);
1034 if (AbiInfo.isSignExt())
1036 if (AbiInfo.isZeroExt())
1040 case llvm::abi::ArgInfo::Indirect: {
1044 AbiInfo.getIndirectByVal(),
1045 AbiInfo.getIndirectRealign());
1047 case llvm::abi::ArgInfo::Ignore:
1050 llvm_unreachable(
"Unexpected llvm::abi::ArgInfo kind");
1061 assert(llvm::all_of(argTypes,
1065 llvm::FoldingSetNodeID ID;
1070 bool isDelegateCall =
1072 unsigned X86ABIAVXLevel = CGM.getABIInfo().getX86ABIAVXLevel(ABIInfoFD, info);
1076 paramInfos, required, resultType, argTypes);
1086 llvm::FoldingSetNodeID ID;
1088 X86ABIAVXLevel, info, paramInfos, required,
1089 resultType, argTypes);
1091 void *insertPos =
nullptr;
1092 CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, insertPos);
1096 unsigned CC = ClangCallConvToLLVMCallConv(info.
getCC());
1100 X86ABIAVXLevel, info, paramInfos, resultType,
1101 argTypes, required);
1102 FunctionInfos.InsertNode(FI, insertPos);
1104 bool inserted = FunctionsBeingProcessed.insert(FI).second;
1106 assert(inserted &&
"Recursively being processed?");
1110 (CC == llvm::CallingConv::SPIR_KERNEL || CC == llvm::CallingConv::C)) {
1115 assert(CC != llvm::CallingConv::C || getContext().getLangOpts().
OpenCL);
1119 }
else if (CGM.shouldUseLLVMABILowering(CC)) {
1120 CGM.computeABIInfoUsingLib(*FI);
1122 CGM.getABIInfo().computeInfo(*FI);
1133 if (I.info.canHaveCoerceToType() && I.info.getCoerceToType() ==
nullptr)
1134 I.info.setCoerceToType(ConvertType(I.type));
1136 bool erased = FunctionsBeingProcessed.erase(FI);
1138 assert(erased &&
"Not in set?");
1144 unsigned llvmCC,
bool instanceMethod,
bool chainCall,
bool delegateCall,
1148 assert(paramInfos.empty() || paramInfos.size() == argTypes.size());
1152 void *buffer =
operator new(totalSizeToAlloc<ArgInfo, ExtParameterInfo>(
1153 argTypes.size() + 1, paramInfos.size()));
1155 CGFunctionInfo *FI =
new (buffer) CGFunctionInfo();
1156 FI->CallingConvention = llvmCC;
1157 FI->EffectiveCallingConvention = llvmCC;
1158 FI->ASTCallingConvention = info.
getCC();
1159 FI->InstanceMethod = instanceMethod;
1160 FI->ChainCall = chainCall;
1161 FI->DelegateCall = delegateCall;
1167 FI->Required = required;
1170 FI->X86ABIAVXLevel = X86ABIAVXLevel;
1171 FI->ArgStruct =
nullptr;
1172 FI->ArgStructAlign = 0;
1173 FI->NumArgs = argTypes.size();
1174 FI->HasExtParameterInfos = !paramInfos.empty();
1175 FI->getArgsBuffer()[0].
type = resultType;
1176 FI->MaxVectorWidth = 0;
1177 for (
unsigned i = 0, e = argTypes.size(); i != e; ++i)
1178 FI->getArgsBuffer()[i + 1].
type = argTypes[i];
1179 for (
unsigned i = 0, e = paramInfos.size(); i != e; ++i)
1180 FI->getExtParameterInfosBuffer()[i] = paramInfos[i];
1190struct TypeExpansion {
1191 enum TypeExpansionKind {
1203 const TypeExpansionKind Kind;
1205 TypeExpansion(TypeExpansionKind K) : Kind(K) {}
1206 virtual ~TypeExpansion() {}
1209struct ConstantArrayExpansion : TypeExpansion {
1213 ConstantArrayExpansion(QualType EltTy, uint64_t NumElts)
1214 : TypeExpansion(TEK_ConstantArray), EltTy(EltTy), NumElts(NumElts) {}
1215 static bool classof(
const TypeExpansion *TE) {
1216 return TE->Kind == TEK_ConstantArray;
1220struct RecordExpansion : TypeExpansion {
1221 SmallVector<const CXXBaseSpecifier *, 1> Bases;
1223 SmallVector<const FieldDecl *, 1> Fields;
1225 RecordExpansion(SmallVector<const CXXBaseSpecifier *, 1> &&Bases,
1226 SmallVector<const FieldDecl *, 1> &&Fields)
1227 : TypeExpansion(TEK_Record), Bases(std::move(Bases)),
1228 Fields(std::move(Fields)) {}
1229 static bool classof(
const TypeExpansion *TE) {
1230 return TE->Kind == TEK_Record;
1234struct ComplexExpansion : TypeExpansion {
1237 ComplexExpansion(QualType EltTy) : TypeExpansion(
TEK_Complex), EltTy(EltTy) {}
1238 static bool classof(
const TypeExpansion *TE) {
1243struct NoExpansion : TypeExpansion {
1244 NoExpansion() : TypeExpansion(TEK_None) {}
1245 static bool classof(
const TypeExpansion *TE) {
return TE->Kind == TEK_None; }
1249static std::unique_ptr<TypeExpansion>
1252 return std::make_unique<ConstantArrayExpansion>(AT->getElementType(),
1258 assert(!RD->hasFlexibleArrayMember() &&
1259 "Cannot expand structure with flexible array.");
1260 if (RD->isUnion()) {
1266 for (
const auto *FD : RD->fields()) {
1267 if (FD->isZeroLengthBitField())
1269 assert(!FD->isBitField() &&
1270 "Cannot expand structure with bit-field members.");
1271 CharUnits FieldSize = Context.getTypeSizeInChars(FD->getType());
1272 if (UnionSize < FieldSize) {
1273 UnionSize = FieldSize;
1278 Fields.push_back(LargestFD);
1280 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
1281 assert(!CXXRD->isDynamicClass() &&
1282 "cannot expand vtable pointers in dynamic classes");
1283 llvm::append_range(Bases, llvm::make_pointer_range(CXXRD->bases()));
1286 for (
const auto *FD : RD->fields()) {
1287 if (FD->isZeroLengthBitField())
1289 assert(!FD->isBitField() &&
1290 "Cannot expand structure with bit-field members.");
1291 Fields.push_back(FD);
1294 return std::make_unique<RecordExpansion>(std::move(Bases),
1298 return std::make_unique<ComplexExpansion>(CT->getElementType());
1300 return std::make_unique<NoExpansion>();
1305 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1308 if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1310 for (
auto BS : RExp->Bases)
1312 for (
auto FD : RExp->Fields)
1325 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1326 for (
int i = 0, n = CAExp->NumElts; i < n; i++) {
1329 }
else if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1330 for (
auto BS : RExp->Bases)
1332 for (
auto FD : RExp->Fields)
1334 }
else if (
auto CExp = dyn_cast<ComplexExpansion>(Exp.get())) {
1345 ConstantArrayExpansion *CAE,
1347 llvm::function_ref<
void(
Address)> Fn) {
1348 for (
int i = 0, n = CAE->NumElts; i < n; i++) {
1354void CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV,
1355 llvm::Function::arg_iterator &AI) {
1356 assert(LV.isSimple() &&
1357 "Unexpected non-simple lvalue during struct expansion.");
1360 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1362 *
this, CAExp, LV.getAddress(), [&](Address EltAddr) {
1363 LValue LV = MakeAddrLValue(EltAddr, CAExp->EltTy);
1364 ExpandTypeFromArgs(CAExp->EltTy, LV, AI);
1366 }
else if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1368 for (
const CXXBaseSpecifier *BS : RExp->Bases) {
1372 false, SourceLocation());
1373 LValue SubLV = MakeAddrLValue(Base, BS->
getType());
1376 ExpandTypeFromArgs(BS->
getType(), SubLV, AI);
1378 for (
auto FD : RExp->Fields) {
1380 LValue SubLV = EmitLValueForFieldInitialization(LV, FD);
1381 ExpandTypeFromArgs(FD->getType(), SubLV, AI);
1384 auto realValue = &*AI++;
1385 auto imagValue = &*AI++;
1386 EmitStoreOfComplex(
ComplexPairTy(realValue, imagValue), LV,
true);
1391 llvm::Value *Arg = &*AI++;
1392 if (LV.isBitField()) {
1398 if (Arg->getType()->isPointerTy()) {
1400 Arg = Builder.CreateBitCast(Arg,
Addr.getElementType());
1402 EmitStoreOfScalar(Arg, LV);
1407void CodeGenFunction::ExpandTypeToArgs(
1408 QualType Ty, CallArg Arg, llvm::FunctionType *IRFuncTy,
1409 SmallVectorImpl<llvm::Value *> &IRCallArgs,
unsigned &IRCallArgPos) {
1411 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1416 CallArg(convertTempToRValue(EltAddr, CAExp->EltTy, SourceLocation()),
1418 ExpandTypeToArgs(CAExp->EltTy, EltArg, IRFuncTy, IRCallArgs,
1421 }
else if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1424 for (
const CXXBaseSpecifier *BS : RExp->Bases) {
1428 false, SourceLocation());
1432 ExpandTypeToArgs(BS->
getType(), BaseArg, IRFuncTy, IRCallArgs,
1436 LValue LV = MakeAddrLValue(This, Ty);
1437 for (
auto FD : RExp->Fields) {
1439 CallArg(EmitRValueForField(LV, FD, SourceLocation()), FD->getType());
1440 ExpandTypeToArgs(FD->getType(), FldArg, IRFuncTy, IRCallArgs,
1445 IRCallArgs[IRCallArgPos++] = CV.first;
1446 IRCallArgs[IRCallArgPos++] = CV.second;
1450 assert(RV.isScalar() &&
1451 "Unexpected non-scalar rvalue during struct expansion.");
1454 llvm::Value *
V = RV.getScalarVal();
1455 if (IRCallArgPos < IRFuncTy->getNumParams() &&
1456 V->getType() != IRFuncTy->getParamType(IRCallArgPos))
1457 V = Builder.CreateBitCast(
V, IRFuncTy->getParamType(IRCallArgPos));
1459 IRCallArgs[IRCallArgPos++] =
V;
1467 const Twine &Name =
"tmp") {
1480 llvm::StructType *SrcSTy,
1484 if (SrcSTy->getNumElements() == 0)
1493 uint64_t FirstEltSize = CGF.
CGM.
getDataLayout().getTypeStoreSize(FirstElt);
1494 if (FirstEltSize < DstSize &&
1503 if (llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy))
1518 if (Val->getType() == Ty)
1524 return CGF.
Builder.CreateBitCast(Val, Ty,
"coerce.val");
1530 llvm::Type *DestIntTy = Ty;
1534 if (Val->getType() != DestIntTy) {
1536 if (DL.isBigEndian()) {
1539 uint64_t SrcSize = DL.getTypeSizeInBits(Val->getType());
1540 uint64_t DstSize = DL.getTypeSizeInBits(DestIntTy);
1542 if (SrcSize > DstSize) {
1543 Val = CGF.
Builder.CreateLShr(Val, SrcSize - DstSize,
"coerce.highbits");
1544 Val = CGF.
Builder.CreateTrunc(Val, DestIntTy,
"coerce.val.ii");
1546 Val = CGF.
Builder.CreateZExt(Val, DestIntTy,
"coerce.val.ii");
1547 Val = CGF.
Builder.CreateShl(Val, DstSize - SrcSize,
"coerce.highbits");
1551 Val = CGF.
Builder.CreateIntCast(Val, DestIntTy,
false,
"coerce.val.ii");
1556 Val = CGF.
Builder.CreateIntToPtr(Val, Ty,
"coerce.val.ip");
1563 if (PFPFields.empty())
1566 auto LoadCoercedField = [&](
CharUnits Offset,
1567 llvm::Type *FieldType) -> llvm::Value * {
1572 if (!PFPFields.empty() && PFPFields[0].Offset == Offset) {
1576 FieldVal = CGF.
Builder.CreatePtrToInt(FieldVal, FieldType);
1577 PFPFields.erase(PFPFields.begin());
1594 Val = CGF.
Builder.CreatePtrToInt(Val, Ty);
1598 auto *ET = AT->getElementType();
1602 llvm::Value *Val = llvm::PoisonValue::get(AT);
1603 for (
unsigned Idx = 0; Idx != AT->getNumElements(); ++Idx, Offset += WordSize)
1604 Val = CGF.
Builder.CreateInsertValue(Val, LoadCoercedField(Offset, ET), Idx);
1628 if (llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy)) {
1630 DstSize.getFixedValue(), CGF);
1645 if (!SrcSize.isScalable() && !DstSize.isScalable() &&
1646 SrcSize.getFixedValue() >= DstSize.getFixedValue()) {
1660 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(Ty)) {
1661 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
1664 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
1665 FixedSrcTy->getElementType()->isIntegerTy(8)) {
1666 ScalableDstTy = llvm::ScalableVectorType::get(
1667 FixedSrcTy->getElementType(),
1669 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
1671 if (ScalableDstTy->getElementType() == FixedSrcTy->getElementType()) {
1673 auto *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
1675 ScalableDstTy, PoisonVec, Load, uint64_t(0),
"cast.scalable");
1677 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, Ty));
1678 if (
Result->getType() != ScalableDstTy)
1680 if (
Result->getType() != Ty)
1693 llvm::ConstantInt::get(CGF.
IntPtrTy, SrcSize.getKnownMinValue()));
1700 if (PFPFields.empty())
1703 llvm::Type *SrcTy = Src->getType();
1704 auto StoreCoercedField = [&](
CharUnits Offset, llvm::Value *FieldVal) {
1705 if (!PFPFields.empty() && PFPFields[0].Offset == Offset) {
1710 PFPFields.erase(PFPFields.begin());
1730 auto *ET = AT->getElementType();
1734 for (
unsigned i = 0; i != AT->getNumElements(); ++i, Offset += WordSize)
1735 StoreCoercedField(Offset, CGF.
Builder.CreateExtractValue(Src, i));
1741 Address Dst, llvm::TypeSize DstSize,
1742 bool DstIsVolatile) {
1746 llvm::Type *SrcTy = Src->getType();
1747 llvm::TypeSize SrcSize =
CGM.getDataLayout().getTypeAllocSize(SrcTy);
1753 if (llvm::StructType *DstSTy =
1755 assert(!SrcSize.isScalable());
1757 SrcSize.getFixedValue(), *
this);
1764 if (SrcSize.isScalable() || SrcSize <= DstSize) {
1765 if (SrcTy->isIntegerTy() && Dst.
getElementType()->isPointerTy() &&
1769 auto *I =
Builder.CreateStore(Src, Dst, DstIsVolatile);
1771 }
else if (llvm::StructType *STy =
1772 dyn_cast<llvm::StructType>(Src->getType())) {
1775 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1777 llvm::Value *Elt =
Builder.CreateExtractValue(Src, i);
1778 auto *I =
Builder.CreateStore(Elt, EltPtr, DstIsVolatile);
1786 }
else if (SrcTy->isIntegerTy()) {
1788 llvm::Type *DstIntTy =
Builder.getIntNTy(DstSize.getFixedValue() * 8);
1805 Builder.CreateStore(Src, Tmp);
1806 auto *I =
Builder.CreateMemCpy(
1825static std::pair<llvm::Value *, bool>
1827 llvm::ScalableVectorType *FromTy, llvm::Value *
V,
1828 StringRef Name =
"") {
1831 if (FromTy->getElementType()->isIntegerTy(1) &&
1832 ToTy->getElementType() == CGF.
Builder.getInt8Ty()) {
1833 if (!FromTy->getElementCount().isKnownMultipleOf(8)) {
1834 FromTy = llvm::ScalableVectorType::get(
1835 FromTy->getElementType(),
1836 llvm::alignTo<8>(FromTy->getElementCount().getKnownMinValue()));
1837 llvm::Value *ZeroVec = llvm::Constant::getNullValue(FromTy);
1838 V = CGF.
Builder.CreateInsertVector(FromTy, ZeroVec,
V, uint64_t(0));
1840 FromTy = llvm::ScalableVectorType::get(
1841 ToTy->getElementType(),
1842 FromTy->getElementCount().getKnownMinValue() / 8);
1843 V = CGF.
Builder.CreateBitCast(
V, FromTy);
1845 if (FromTy->getElementType() == ToTy->getElementType()) {
1846 V->setName(Name +
".coerce");
1847 V = CGF.
Builder.CreateExtractVector(ToTy,
V, uint64_t(0),
"cast.fixed");
1857class ClangToLLVMArgMapping {
1858 static const unsigned InvalidIndex = ~0U;
1859 unsigned InallocaArgNo;
1861 unsigned TotalIRArgs;
1865 unsigned PaddingArgIndex;
1868 unsigned FirstArgIndex;
1869 unsigned NumberOfArgs;
1872 : PaddingArgIndex(InvalidIndex), FirstArgIndex(InvalidIndex),
1876 SmallVector<IRArgs, 8> ArgInfo;
1879 ClangToLLVMArgMapping(
const ASTContext &Context,
const CGFunctionInfo &FI,
1880 bool OnlyRequiredArgs =
false)
1881 : InallocaArgNo(InvalidIndex), SRetArgNo(InvalidIndex), TotalIRArgs(0),
1882 ArgInfo(OnlyRequiredArgs ? FI.getNumRequiredArgs() : FI.arg_size()) {
1883 construct(Context, FI, OnlyRequiredArgs);
1886 bool hasInallocaArg()
const {
return InallocaArgNo != InvalidIndex; }
1887 unsigned getInallocaArgNo()
const {
1888 assert(hasInallocaArg());
1889 return InallocaArgNo;
1892 bool hasSRetArg()
const {
return SRetArgNo != InvalidIndex; }
1893 unsigned getSRetArgNo()
const {
1894 assert(hasSRetArg());
1898 unsigned totalIRArgs()
const {
return TotalIRArgs; }
1900 bool hasPaddingArg(
unsigned ArgNo)
const {
1901 assert(ArgNo < ArgInfo.size());
1902 return ArgInfo[ArgNo].PaddingArgIndex != InvalidIndex;
1904 unsigned getPaddingArgNo(
unsigned ArgNo)
const {
1905 assert(hasPaddingArg(ArgNo));
1906 return ArgInfo[ArgNo].PaddingArgIndex;
1911 std::pair<unsigned, unsigned> getIRArgs(
unsigned ArgNo)
const {
1912 assert(ArgNo < ArgInfo.size());
1913 return std::make_pair(ArgInfo[ArgNo].FirstArgIndex,
1914 ArgInfo[ArgNo].NumberOfArgs);
1918 void construct(
const ASTContext &Context,
const CGFunctionInfo &FI,
1919 bool OnlyRequiredArgs);
1922void ClangToLLVMArgMapping::construct(
const ASTContext &Context,
1923 const CGFunctionInfo &FI,
1924 bool OnlyRequiredArgs) {
1925 unsigned IRArgNo = 0;
1926 bool SwapThisWithSRet =
false;
1931 SRetArgNo = SwapThisWithSRet ? 1 : IRArgNo++;
1939 QualType ArgType = I->type;
1940 const ABIArgInfo &AI = I->info;
1942 auto &IRArgs = ArgInfo[ArgNo];
1945 IRArgs.PaddingArgIndex = IRArgNo++;
1952 llvm::StructType *STy = dyn_cast<llvm::StructType>(AI.
getCoerceToType());
1954 IRArgs.NumberOfArgs = STy->getNumElements();
1956 IRArgs.NumberOfArgs = 1;
1962 IRArgs.NumberOfArgs = 1;
1967 IRArgs.NumberOfArgs = 0;
1977 if (IRArgs.NumberOfArgs > 0) {
1978 IRArgs.FirstArgIndex = IRArgNo;
1979 IRArgNo += IRArgs.NumberOfArgs;
1984 if (IRArgNo == 1 && SwapThisWithSRet)
1987 assert(ArgNo == ArgInfo.size());
1990 InallocaArgNo = IRArgNo++;
1992 TotalIRArgs = IRArgNo;
2000 return RI.
isIndirect() || (RI.isInAlloca() && RI.getInAllocaSRet());
2015 switch (BT->getKind()) {
2018 case BuiltinType::Float:
2020 case BuiltinType::Double:
2022 case BuiltinType::LongDouble:
2033 if (BT->getKind() == BuiltinType::LongDouble)
2034 return getTarget().useObjCFP2RetForComplexLongDouble();
2048 bool Inserted = FunctionsBeingProcessed.insert(&FI).second;
2050 assert(Inserted &&
"Recursively being processed?");
2052 llvm::Type *resultType =
nullptr;
2057 llvm_unreachable(
"Invalid ABI kind for return argument");
2069 unsigned addressSpace = CGM.getTypes().getTargetAddressSpace(ret);
2070 resultType = llvm::PointerType::get(
getLLVMContext(), addressSpace);
2086 ClangToLLVMArgMapping IRFunctionArgs(
getContext(), FI,
true);
2090 if (IRFunctionArgs.hasSRetArg()) {
2091 ArgTypes[IRFunctionArgs.getSRetArgNo()] = llvm::PointerType::get(
2096 if (IRFunctionArgs.hasInallocaArg())
2097 ArgTypes[IRFunctionArgs.getInallocaArgNo()] =
2104 for (; it != ie; ++it, ++ArgNo) {
2108 if (IRFunctionArgs.hasPaddingArg(ArgNo))
2109 ArgTypes[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
2112 unsigned FirstIRArg, NumIRArgs;
2113 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
2118 assert(NumIRArgs == 0);
2122 assert(NumIRArgs == 1);
2124 ArgTypes[FirstIRArg] = llvm::PointerType::get(
2128 assert(NumIRArgs == 1);
2129 ArgTypes[FirstIRArg] = llvm::PointerType::get(
2138 llvm::StructType *st = dyn_cast<llvm::StructType>(argType);
2140 assert(NumIRArgs == st->getNumElements());
2141 for (
unsigned i = 0, e = st->getNumElements(); i != e; ++i)
2142 ArgTypes[FirstIRArg + i] = st->getElementType(i);
2144 assert(NumIRArgs == 1);
2145 ArgTypes[FirstIRArg] = argType;
2151 auto ArgTypesIter = ArgTypes.begin() + FirstIRArg;
2153 *ArgTypesIter++ = EltTy;
2155 assert(ArgTypesIter == ArgTypes.begin() + FirstIRArg + NumIRArgs);
2160 auto ArgTypesIter = ArgTypes.begin() + FirstIRArg;
2162 assert(ArgTypesIter == ArgTypes.begin() + FirstIRArg + NumIRArgs);
2167 bool Erased = FunctionsBeingProcessed.erase(&FI);
2169 assert(Erased &&
"Not in set?");
2171 return llvm::FunctionType::get(resultType, ArgTypes, FI.
isVariadic());
2185 llvm::AttrBuilder &FuncAttrs,
2192 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2196 FuncAttrs.addAttribute(
"aarch64_pstate_sm_enabled");
2198 FuncAttrs.addAttribute(
"aarch64_pstate_sm_compatible");
2200 FuncAttrs.addAttribute(
"aarch64_za_state_agnostic");
2204 FuncAttrs.addAttribute(
"aarch64_preserves_za");
2206 FuncAttrs.addAttribute(
"aarch64_in_za");
2208 FuncAttrs.addAttribute(
"aarch64_out_za");
2210 FuncAttrs.addAttribute(
"aarch64_inout_za");
2214 FuncAttrs.addAttribute(
"aarch64_preserves_zt0");
2216 FuncAttrs.addAttribute(
"aarch64_in_zt0");
2218 FuncAttrs.addAttribute(
"aarch64_out_zt0");
2220 FuncAttrs.addAttribute(
"aarch64_inout_zt0");
2224 const Decl *Callee) {
2230 for (
const OMPAssumeAttr *AA : Callee->specific_attrs<OMPAssumeAttr>())
2231 AA->getAssumption().split(Attrs,
",");
2234 FuncAttrs.addAttribute(llvm::AssumptionAttrKey,
2235 llvm::join(Attrs.begin(), Attrs.end(),
","));
2242 if (
const RecordType *RT =
2244 if (
const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl()))
2245 return ClassDecl->hasTrivialDestructor();
2251 const Decl *TargetDecl) {
2257 if (
Module.getLangOpts().Sanitize.has(SanitizerKind::Memory))
2261 if (!
Module.getLangOpts().CPlusPlus)
2264 if (
const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(TargetDecl)) {
2265 if (FDecl->isExternC())
2267 }
else if (
const VarDecl *VDecl = dyn_cast<VarDecl>(TargetDecl)) {
2269 if (VDecl->isExternC())
2277 return Module.getCodeGenOpts().StrictReturn ||
2278 !
Module.MayDropFunctionReturn(
Module.getContext(), RetTy) ||
2279 Module.getLangOpts().Sanitize.has(SanitizerKind::Return);
2286 llvm::DenormalMode FP32DenormalMode,
2287 llvm::AttrBuilder &FuncAttrs) {
2288 llvm::DenormalFPEnv FPEnv(FPDenormalMode, FP32DenormalMode);
2289 if (FPEnv != llvm::DenormalFPEnv::getDefault())
2290 FuncAttrs.addDenormalFPEnvAttr(FPEnv);
2298 llvm::AttrBuilder &FuncAttrs) {
2304 StringRef Name,
bool HasOptnone,
const CodeGenOptions &CodeGenOpts,
2306 llvm::AttrBuilder &FuncAttrs) {
2309 if (CodeGenOpts.OptimizeSize)
2310 FuncAttrs.addAttribute(llvm::Attribute::OptimizeForSize);
2311 if (CodeGenOpts.OptimizeSize == 2)
2312 FuncAttrs.addAttribute(llvm::Attribute::MinSize);
2315 if (CodeGenOpts.DisableRedZone)
2316 FuncAttrs.addAttribute(llvm::Attribute::NoRedZone);
2317 if (CodeGenOpts.IndirectTlsSegRefs)
2318 FuncAttrs.addAttribute(
"indirect-tls-seg-refs");
2319 if (CodeGenOpts.NoImplicitFloat)
2320 FuncAttrs.addAttribute(llvm::Attribute::NoImplicitFloat);
2322 if (AttrOnCallSite) {
2327 FuncAttrs.addAttribute(llvm::Attribute::NoBuiltin);
2329 FuncAttrs.addAttribute(
"trap-func-name", CodeGenOpts.
TrapFuncName);
2331 switch (CodeGenOpts.getFramePointer()) {
2339 FuncAttrs.addAttribute(
"frame-pointer",
2341 CodeGenOpts.getFramePointer()));
2344 if (CodeGenOpts.LessPreciseFPMAD)
2345 FuncAttrs.addAttribute(
"less-precise-fpmad",
"true");
2347 if (CodeGenOpts.NullPointerIsValid)
2348 FuncAttrs.addAttribute(llvm::Attribute::NullPointerIsValid);
2351 FuncAttrs.addAttribute(
"no-trapping-math",
"true");
2355 if (CodeGenOpts.SoftFloat)
2356 FuncAttrs.addAttribute(
"use-soft-float",
"true");
2357 FuncAttrs.addAttribute(
"stack-protector-buffer-size",
2358 llvm::utostr(CodeGenOpts.SSPBufferSize));
2359 if (LangOpts.NoSignedZero)
2360 FuncAttrs.addAttribute(
"no-signed-zeros-fp-math",
"true");
2363 const std::vector<std::string> &Recips = CodeGenOpts.
Reciprocals;
2364 if (!Recips.empty())
2365 FuncAttrs.addAttribute(
"reciprocal-estimates", llvm::join(Recips,
","));
2369 FuncAttrs.addAttribute(
"prefer-vector-width",
2372 if (CodeGenOpts.StackRealignment)
2373 FuncAttrs.addAttribute(
"stackrealign");
2374 if (CodeGenOpts.Backchain)
2375 FuncAttrs.addAttribute(
"backchain");
2376 if (CodeGenOpts.EnableSegmentedStacks)
2377 FuncAttrs.addAttribute(
"split-stack");
2379 if (CodeGenOpts.SpeculativeLoadHardening)
2380 FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
2383 switch (CodeGenOpts.getZeroCallUsedRegs()) {
2384 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Skip:
2385 FuncAttrs.removeAttribute(
"zero-call-used-regs");
2387 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPRArg:
2388 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used-gpr-arg");
2390 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPR:
2391 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used-gpr");
2393 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedArg:
2394 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used-arg");
2396 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Used:
2397 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used");
2399 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPRArg:
2400 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all-gpr-arg");
2402 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPR:
2403 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all-gpr");
2405 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllArg:
2406 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all-arg");
2408 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::All:
2409 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all");
2420 FuncAttrs.addAttribute(llvm::Attribute::Convergent);
2425 if ((LangOpts.CUDA && LangOpts.CUDAIsDevice) || LangOpts.OpenCL ||
2426 LangOpts.SYCLIsDevice) {
2427 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2430 if (CodeGenOpts.SaveRegParams && !AttrOnCallSite)
2431 FuncAttrs.addAttribute(
"save-reg-params");
2434 StringRef Var,
Value;
2436 FuncAttrs.addAttribute(Var,
Value);
2450 const llvm::Function &F,
2452 auto FFeatures = F.getFnAttribute(
"target-features");
2454 llvm::StringSet<> MergedNames;
2456 MergedFeatures.reserve(TargetOpts.
Features.size());
2458 auto AddUnmergedFeatures = [&](
auto &&FeatureRange) {
2459 for (StringRef
Feature : FeatureRange) {
2463 StringRef Name =
Feature.drop_front(1);
2464 bool Merged = !MergedNames.insert(Name).second;
2466 MergedFeatures.push_back(
Feature);
2470 if (FFeatures.isValid())
2471 AddUnmergedFeatures(llvm::split(FFeatures.getValueAsString(),
','));
2472 AddUnmergedFeatures(TargetOpts.
Features);
2474 if (!MergedFeatures.empty()) {
2475 llvm::sort(MergedFeatures);
2476 FuncAttr.addAttribute(
"target-features", llvm::join(MergedFeatures,
","));
2483 bool WillInternalize) {
2485 llvm::AttrBuilder FuncAttrs(F.getContext());
2488 if (!TargetOpts.
CPU.empty())
2489 FuncAttrs.addAttribute(
"target-cpu", TargetOpts.
CPU);
2490 if (!TargetOpts.
TuneCPU.empty())
2491 FuncAttrs.addAttribute(
"tune-cpu", TargetOpts.
TuneCPU);
2494 CodeGenOpts, LangOpts,
2497 if (!WillInternalize && F.isInterposable()) {
2502 F.addFnAttrs(FuncAttrs);
2506 llvm::AttributeMask AttrsToRemove;
2510 llvm::DenormalFPEnv MergedFPEnv =
2511 OptsFPEnv.mergeCalleeMode(F.getDenormalFPEnv());
2513 if (MergedFPEnv == llvm::DenormalFPEnv::getDefault()) {
2514 AttrsToRemove.addAttribute(llvm::Attribute::DenormalFPEnv);
2517 FuncAttrs.addDenormalFPEnvAttr(MergedFPEnv);
2520 F.removeFnAttrs(AttrsToRemove);
2524 F.addFnAttrs(FuncAttrs);
2527void CodeGenModule::getTrivialDefaultFunctionAttributes(
2528 StringRef Name,
bool HasOptnone,
bool AttrOnCallSite,
2529 llvm::AttrBuilder &FuncAttrs) {
2531 getLangOpts(), AttrOnCallSite,
2535void CodeGenModule::getDefaultFunctionAttributes(StringRef Name,
2537 bool AttrOnCallSite,
2538 llvm::AttrBuilder &FuncAttrs) {
2542 if (!AttrOnCallSite)
2548 if (!AttrOnCallSite)
2553 llvm::AttrBuilder &attrs) {
2554 getDefaultFunctionAttributes(
"",
false,
2556 GetCPUAndFeaturesAttributes(
GlobalDecl(), attrs);
2561 const NoBuiltinAttr *NBA =
nullptr) {
2562 auto AddNoBuiltinAttr = [&FuncAttrs](StringRef BuiltinName) {
2564 AttributeName +=
"no-builtin-";
2565 AttributeName += BuiltinName;
2566 FuncAttrs.addAttribute(AttributeName);
2570 if (LangOpts.NoBuiltin) {
2572 FuncAttrs.addAttribute(
"no-builtins");
2586 if (llvm::is_contained(NBA->builtinNames(),
"*")) {
2587 FuncAttrs.addAttribute(
"no-builtins");
2592 llvm::for_each(NBA->builtinNames(), AddNoBuiltinAttr);
2596 const llvm::DataLayout &DL,
const ABIArgInfo &AI,
2597 bool CheckCoerce =
true) {
2604 if (!DL.typeSizeEqualsStoreSize(Ty))
2611 if (llvm::TypeSize::isKnownGT(DL.getTypeSizeInBits(CoerceTy),
2612 DL.getTypeSizeInBits(Ty)))
2636 if (
const MatrixType *Matrix = dyn_cast<MatrixType>(QTy))
2647 unsigned NumRequiredArgs,
unsigned ArgNo) {
2648 const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl);
2653 if (ArgNo >= NumRequiredArgs)
2657 if (ArgNo < FD->getNumParams()) {
2658 const ParmVarDecl *Param = FD->getParamDecl(ArgNo);
2659 if (Param && Param->hasAttr<MaybeUndefAttr>())
2676 if (llvm::AttributeFuncs::isNoFPClassCompatibleType(IRTy))
2679 if (llvm::StructType *ST = dyn_cast<llvm::StructType>(IRTy)) {
2681 llvm::all_of(ST->elements(),
2682 llvm::AttributeFuncs::isNoFPClassCompatibleType);
2690 llvm::FPClassTest Mask = llvm::fcNone;
2691 if (LangOpts.NoHonorInfs)
2692 Mask |= llvm::fcInf;
2693 if (LangOpts.NoHonorNaNs)
2694 Mask |= llvm::fcNan;
2700 llvm::AttributeList &Attrs) {
2701 if (Attrs.getMemoryEffects().getModRef() == llvm::ModRefInfo::NoModRef) {
2702 Attrs = Attrs.removeFnAttribute(
getLLVMContext(), llvm::Attribute::Memory);
2703 llvm::Attribute MemoryAttr = llvm::Attribute::getWithMemoryEffects(
2729 llvm::AttributeList &AttrList,
2731 bool AttrOnCallSite,
bool IsThunk) {
2739 FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2741 FuncAttrs.addAttribute(
"cmse_nonsecure_call");
2752 bool HasOptnone =
false;
2754 const NoBuiltinAttr *NBA =
nullptr;
2758 std::optional<llvm::Attribute::AttrKind> MemAttrForPtrArgs;
2759 bool AddedPotentialArgAccess =
false;
2760 auto AddPotentialArgAccess = [&]() {
2761 AddedPotentialArgAccess =
true;
2762 llvm::Attribute A = FuncAttrs.getAttribute(llvm::Attribute::Memory);
2764 FuncAttrs.addMemoryAttr(A.getMemoryEffects() |
2765 llvm::MemoryEffects::argMemOnly());
2772 if (TargetDecl->
hasAttr<ReturnsTwiceAttr>())
2773 FuncAttrs.addAttribute(llvm::Attribute::ReturnsTwice);
2774 if (TargetDecl->
hasAttr<NoThrowAttr>())
2775 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2776 if (TargetDecl->
hasAttr<NoReturnAttr>())
2777 FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2778 if (TargetDecl->
hasAttr<ColdAttr>())
2779 FuncAttrs.addAttribute(llvm::Attribute::Cold);
2780 if (TargetDecl->
hasAttr<HotAttr>())
2781 FuncAttrs.addAttribute(llvm::Attribute::Hot);
2782 if (TargetDecl->
hasAttr<NoDuplicateAttr>())
2783 FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate);
2784 if (TargetDecl->
hasAttr<ConvergentAttr>())
2785 FuncAttrs.addAttribute(llvm::Attribute::Convergent);
2787 if (
const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
2790 if (AttrOnCallSite && Fn->isReplaceableGlobalAllocationFunction()) {
2792 auto Kind = Fn->getDeclName().getCXXOverloadedOperator();
2794 (Kind == OO_New || Kind == OO_Array_New))
2795 RetAttrs.addAttribute(llvm::Attribute::NoAlias);
2798 const bool IsVirtualCall = MD && MD->
isVirtual();
2801 if (!(AttrOnCallSite && IsVirtualCall)) {
2802 if (Fn->isNoReturn())
2803 FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2804 NBA = Fn->getAttr<NoBuiltinAttr>();
2811 if (AttrOnCallSite && TargetDecl->
hasAttr<NoMergeAttr>())
2812 FuncAttrs.addAttribute(llvm::Attribute::NoMerge);
2816 if (TargetDecl->
hasAttr<ConstAttr>()) {
2817 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::none());
2818 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2821 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
2822 MemAttrForPtrArgs = llvm::Attribute::ReadNone;
2823 }
else if (TargetDecl->
hasAttr<PureAttr>()) {
2824 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
2825 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2827 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
2828 MemAttrForPtrArgs = llvm::Attribute::ReadOnly;
2829 }
else if (TargetDecl->
hasAttr<NoAliasAttr>()) {
2830 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::inaccessibleOrArgMemOnly());
2831 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2833 if (
const auto *RA = TargetDecl->
getAttr<RestrictAttr>();
2834 RA && RA->getDeallocator() ==
nullptr)
2835 RetAttrs.addAttribute(llvm::Attribute::NoAlias);
2836 if (TargetDecl->
hasAttr<ReturnsNonNullAttr>() &&
2837 !CodeGenOpts.NullPointerIsValid)
2838 RetAttrs.addAttribute(llvm::Attribute::NonNull);
2839 if (TargetDecl->
hasAttr<AnyX86NoCallerSavedRegistersAttr>())
2840 FuncAttrs.addAttribute(
"no_caller_saved_registers");
2841 if (TargetDecl->
hasAttr<AnyX86NoCfCheckAttr>())
2842 FuncAttrs.addAttribute(llvm::Attribute::NoCfCheck);
2843 if (TargetDecl->
hasAttr<LeafAttr>())
2844 FuncAttrs.addAttribute(llvm::Attribute::NoCallback);
2845 if (TargetDecl->
hasAttr<BPFFastCallAttr>())
2846 FuncAttrs.addAttribute(
"bpf_fastcall");
2848 HasOptnone = TargetDecl->
hasAttr<OptimizeNoneAttr>();
2849 if (
auto *AllocSize = TargetDecl->
getAttr<AllocSizeAttr>()) {
2850 std::optional<unsigned> NumElemsParam;
2851 if (AllocSize->getNumElemsParam().isValid())
2852 NumElemsParam = AllocSize->getNumElemsParam().getLLVMIndex();
2853 FuncAttrs.addAllocSizeAttr(AllocSize->getElemSizeParam().getLLVMIndex(),
2863 FuncAttrs.addAttribute(
"uniform-work-group-size");
2865 if (TargetDecl->
hasAttr<ArmLocallyStreamingAttr>())
2866 FuncAttrs.addAttribute(
"aarch64_pstate_sm_body");
2868 if (
auto *ModularFormat = TargetDecl->
getAttr<ModularFormatAttr>()) {
2869 FormatAttr *Format = TargetDecl->
getAttr<FormatAttr>();
2870 StringRef
Type = Format->getType()->getName();
2871 std::string FormatIdx = std::to_string(Format->getFormatIdx());
2872 std::string FirstArg = std::to_string(Format->getFirstArg());
2874 Type, FormatIdx, FirstArg,
2875 ModularFormat->getModularImplFn()->getName(),
2876 ModularFormat->getImplName()};
2877 llvm::append_range(Args, ModularFormat->aspects());
2878 FuncAttrs.addAttribute(
"modular-format", llvm::join(Args,
","));
2891 getDefaultFunctionAttributes(Name, HasOptnone, AttrOnCallSite, FuncAttrs);
2896 if (TargetDecl->
hasAttr<NoSpeculativeLoadHardeningAttr>())
2897 FuncAttrs.removeAttribute(llvm::Attribute::SpeculativeLoadHardening);
2898 if (TargetDecl->
hasAttr<SpeculativeLoadHardeningAttr>())
2899 FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
2900 if (TargetDecl->
hasAttr<NoSplitStackAttr>())
2901 FuncAttrs.removeAttribute(
"split-stack");
2902 if (TargetDecl->
hasAttr<ZeroCallUsedRegsAttr>()) {
2905 TargetDecl->
getAttr<ZeroCallUsedRegsAttr>()->getZeroCallUsedRegs();
2906 FuncAttrs.removeAttribute(
"zero-call-used-regs");
2907 FuncAttrs.addAttribute(
2908 "zero-call-used-regs",
2909 ZeroCallUsedRegsAttr::ConvertZeroCallUsedRegsKindToStr(Kind));
2916 if (CodeGenOpts.NoPLT) {
2917 if (
auto *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
2918 if (!Fn->isDefined() && !AttrOnCallSite) {
2919 FuncAttrs.addAttribute(llvm::Attribute::NonLazyBind);
2924 if (TargetDecl->
hasAttr<NoConvergentAttr>())
2925 FuncAttrs.removeAttribute(llvm::Attribute::Convergent);
2930 if (TargetDecl && CodeGenOpts.UniqueInternalLinkageNames) {
2931 if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
2932 if (!FD->isExternallyVisible())
2933 FuncAttrs.addAttribute(
"sample-profile-suffix-elision-policy",
2940 if (!AttrOnCallSite) {
2941 if (TargetDecl && TargetDecl->
hasAttr<CmseNSEntryAttr>())
2942 FuncAttrs.addAttribute(
"cmse_nonsecure_entry");
2945 auto shouldDisableTailCalls = [&] {
2947 if (CodeGenOpts.DisableTailCalls)
2953 if (TargetDecl->
hasAttr<DisableTailCallsAttr>() ||
2954 TargetDecl->
hasAttr<AnyX86InterruptAttr>())
2957 if (CodeGenOpts.NoEscapingBlockTailCalls) {
2958 if (
const auto *BD = dyn_cast<BlockDecl>(TargetDecl))
2959 if (!BD->doesNotEscape())
2965 if (shouldDisableTailCalls())
2966 FuncAttrs.addAttribute(
"disable-tail-calls",
"true");
2971 static const llvm::StringSet<> ReturnsTwiceFn{
2972 "_setjmpex",
"setjmp",
"_setjmp",
"vfork",
2973 "sigsetjmp",
"__sigsetjmp",
"savectx",
"getcontext"};
2974 if (ReturnsTwiceFn.contains(Name))
2975 FuncAttrs.addAttribute(llvm::Attribute::ReturnsTwice);
2979 GetCPUAndFeaturesAttributes(CalleeInfo.
getCalleeDecl(), FuncAttrs);
2982 if (!MSHotPatchFunctions.empty()) {
2983 bool IsHotPatched = llvm::binary_search(MSHotPatchFunctions, Name);
2985 FuncAttrs.addAttribute(
"marked_for_windows_hot_patching");
2990 if (CodeGenOpts.isLoaderReplaceableFunctionName(Name))
2991 FuncAttrs.addAttribute(
"loader-replaceable");
2994 ClangToLLVMArgMapping IRFunctionArgs(
getContext(), FI);
3001 if (CodeGenOpts.EnableNoundefAttrs &&
3005 RetAttrs.addAttribute(llvm::Attribute::NoUndef);
3011 RetAttrs.addAttribute(llvm::Attribute::SExt);
3013 RetAttrs.addAttribute(llvm::Attribute::ZExt);
3015 RetAttrs.addAttribute(llvm::Attribute::NoExt);
3020 RetAttrs.addAttribute(llvm::Attribute::InReg);
3032 AddPotentialArgAccess();
3041 llvm_unreachable(
"Invalid ABI kind for return argument");
3049 RetAttrs.addDereferenceableAttr(
3051 if (
getTypes().getTargetAddressSpace(PTy) == 0 &&
3052 !CodeGenOpts.NullPointerIsValid)
3053 RetAttrs.addAttribute(llvm::Attribute::NonNull);
3055 llvm::Align Alignment =
3057 RetAttrs.addAlignmentAttr(Alignment);
3062 bool hasUsedSRet =
false;
3064 for (
unsigned I = 0; I < IRFunctionArgs.totalIRArgs(); ++I)
3068 if (IRFunctionArgs.hasSRetArg()) {
3069 llvm::AttrBuilder &SRETAttrs = ArgAttrs[IRFunctionArgs.getSRetArgNo()];
3070 SRETAttrs.addStructRetAttr(
getTypes().ConvertTypeForMem(RetTy));
3071 SRETAttrs.addAttribute(llvm::Attribute::Writable);
3072 SRETAttrs.addAttribute(llvm::Attribute::DeadOnUnwind);
3075 SRETAttrs.addAttribute(llvm::Attribute::InReg);
3080 if (IRFunctionArgs.hasInallocaArg()) {
3081 ArgAttrs[IRFunctionArgs.getInallocaArgNo()].addInAllocaAttr(
3091 auto IRArgs = IRFunctionArgs.getIRArgs(0);
3093 assert(IRArgs.second == 1 &&
"Expected only a single `this` pointer.");
3095 llvm::AttrBuilder &Attrs = ArgAttrs[IRArgs.first];
3100 if (!CodeGenOpts.NullPointerIsValid &&
3102 Attrs.addAttribute(llvm::Attribute::NonNull);
3103 Attrs.addDereferenceableAttr(ThisSz);
3109 Attrs.addDereferenceableOrNullAttr(ThisSz);
3112 llvm::Align Alignment =
3116 Attrs.addAlignmentAttr(Alignment);
3118 const auto *DD = dyn_cast_if_present<CXXDestructorDecl>(
3132 CodeGenOpts.StrictLifetimes) {
3134 dyn_cast<CXXRecordDecl>(DD->getDeclContext());
3138 Attrs.addDeadOnReturnAttr(llvm::DeadOnReturnInfo(
3139 Context.getASTRecordLayout(ClassDecl).getDataSize().getQuantity()));
3145 I != E; ++I, ++ArgNo) {
3151 if (IRFunctionArgs.hasPaddingArg(ArgNo)) {
3153 ArgAttrs[IRFunctionArgs.getPaddingArgNo(ArgNo)].addAttribute(
3154 llvm::Attribute::InReg);
3159 if (CodeGenOpts.EnableNoundefAttrs &&
3161 Attrs.addAttribute(llvm::Attribute::NoUndef);
3170 Attrs.addAttribute(llvm::Attribute::SExt);
3172 Attrs.addAttribute(llvm::Attribute::ZExt);
3174 Attrs.addAttribute(llvm::Attribute::NoExt);
3179 Attrs.addAttribute(llvm::Attribute::Nest);
3181 Attrs.addAttribute(llvm::Attribute::InReg);
3182 Attrs.addStackAlignmentAttr(llvm::MaybeAlign(AI.
getDirectAlign()));
3189 Attrs.addAttribute(llvm::Attribute::InReg);
3201 Attrs.addByValAttr(
getTypes().ConvertTypeForMem(ParamType));
3209 Attrs.addDeadOnReturnAttr(llvm::DeadOnReturnInfo());
3214 if (CodeGenOpts.PassByValueIsNoAlias &&
Decl &&
3215 Decl->getArgPassingRestrictions() ==
3219 Attrs.addAttribute(llvm::Attribute::NoAlias);
3242 AddPotentialArgAccess();
3247 Attrs.addByRefAttr(
getTypes().ConvertTypeForMem(ParamType));
3258 AddPotentialArgAccess();
3266 if (
getTypes().getTargetAddressSpace(PTy) == 0 &&
3267 !CodeGenOpts.NullPointerIsValid)
3268 Attrs.addAttribute(llvm::Attribute::NonNull);
3270 llvm::Align Alignment =
3272 Attrs.addAlignmentAttr(Alignment);
3281 DeviceKernelAttr::isOpenCLSpelling(
3282 TargetDecl->
getAttr<DeviceKernelAttr>()) &&
3286 llvm::Align Alignment =
3288 Attrs.addAlignmentAttr(Alignment);
3295 Attrs.addAttribute(llvm::Attribute::NoAlias);
3304 Attrs.addStructRetAttr(
getTypes().ConvertTypeForMem(ParamType));
3309 Attrs.addAttribute(llvm::Attribute::NoAlias);
3313 if (!PTy->isIncompleteType() && PTy->isConstantSizeType()) {
3314 auto info =
getContext().getTypeInfoInChars(PTy);
3315 Attrs.addDereferenceableAttr(info.Width.getQuantity());
3316 Attrs.addAlignmentAttr(info.Align.getAsAlign());
3322 Attrs.addAttribute(llvm::Attribute::SwiftError);
3326 Attrs.addAttribute(llvm::Attribute::SwiftSelf);
3330 Attrs.addAttribute(llvm::Attribute::SwiftAsync);
3335 Attrs.addCapturesAttr(
3336 llvm::CaptureInfo(llvm::CaptureComponents::Address));
3338 if (Attrs.hasAttributes()) {
3339 unsigned FirstIRArg, NumIRArgs;
3340 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
3341 for (
unsigned i = 0; i < NumIRArgs; i++)
3342 ArgAttrs[FirstIRArg + i].merge(Attrs);
3350 AddPotentialArgAccess();
3353 if (AddedPotentialArgAccess && MemAttrForPtrArgs) {
3357 I != E; ++I, ++ArgNo) {
3358 if (I->info.isDirect() || I->info.isExpand() ||
3359 I->info.isCoerceAndExpand()) {
3360 unsigned FirstIRArg, NumIRArgs;
3361 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
3362 for (
unsigned i = FirstIRArg; i < FirstIRArg + NumIRArgs; ++i) {
3369 if (i < FunctionType->getNumParams() &&
3371 ArgAttrs[i].addAttribute(*MemAttrForPtrArgs);
3379 for (
const llvm::AttrBuilder &Attrs : ArgAttrs)
3380 ArgAttrSets.push_back(llvm::AttributeSet::get(
getLLVMContext(), Attrs));
3382 AttrList = llvm::AttributeList::get(
3384 llvm::AttributeSet::get(
getLLVMContext(), RetAttrs), ArgAttrSets);
3391 llvm::Value *value) {
3392 llvm::Type *varType = CGF.
ConvertType(var->getType());
3396 if (value->getType() == varType)
3399 assert((varType->isIntegerTy() || varType->isFloatingPointTy()) &&
3400 "unexpected promotion type");
3403 return CGF.
Builder.CreateTrunc(value, varType,
"arg.unpromote");
3405 return CGF.
Builder.CreateFPCast(value, varType,
"arg.unpromote");
3411 QualType ArgType,
unsigned ArgNo) {
3419 if (!ArgType->isAnyPointerType() && !ArgType->isBlockPointerType())
3423 if (
auto ParmNNAttr = PVD->
getAttr<NonNullAttr>())
3430 if (NNAttr->isNonNull(ArgNo))
3437struct CopyBackSwiftError final : EHScopeStack::Cleanup {
3440 CopyBackSwiftError(Address temp, Address arg) : Temp(temp), Arg(
arg) {}
3441 void Emit(CodeGenFunction &CGF, Flags flags)
override {
3460 if (FD->hasImplicitReturnZero()) {
3461 QualType RetTy = FD->getReturnType().getUnqualifiedType();
3462 llvm::Type *LLVMTy =
CGM.getTypes().ConvertType(RetTy);
3463 llvm::Constant *
Zero = llvm::Constant::getNullValue(LLVMTy);
3471 ClangToLLVMArgMapping IRFunctionArgs(
CGM.getContext(), FI);
3472 assert(Fn->arg_size() == IRFunctionArgs.totalIRArgs());
3477 if (IRFunctionArgs.hasInallocaArg())
3478 ArgStruct =
Address(Fn->getArg(IRFunctionArgs.getInallocaArgNo()),
3482 if (IRFunctionArgs.hasSRetArg()) {
3483 auto AI = Fn->getArg(IRFunctionArgs.getSRetArgNo());
3484 AI->setName(
"agg.result");
3485 AI->addAttr(llvm::Attribute::NoAlias);
3492 ArgVals.reserve(Args.size());
3498 assert(FI.
arg_size() == Args.size() &&
3499 "Mismatch between function signature & arguments.");
3502 for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); i != e;
3503 ++i, ++info_it, ++ArgNo) {
3516 unsigned FirstIRArg, NumIRArgs;
3517 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
3521 assert(NumIRArgs == 0);
3534 assert(NumIRArgs == 1);
3557 llvm::ConstantInt::get(
IntPtrTy, Size.getQuantity()));
3558 ParamAddr = AlignedTemp;
3575 auto AI = Fn->getArg(FirstIRArg);
3583 assert(NumIRArgs == 1);
3585 if (
const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(Arg)) {
3588 PVD->getFunctionScopeIndex()) &&
3589 !
CGM.getCodeGenOpts().NullPointerIsValid)
3590 AI->addAttr(llvm::Attribute::NonNull);
3592 QualType OTy = PVD->getOriginalType();
3593 if (
const auto *ArrTy =
getContext().getAsConstantArrayType(OTy)) {
3599 QualType ETy = ArrTy->getElementType();
3600 llvm::Align Alignment =
3601 CGM.getNaturalTypeAlignment(ETy).getAsAlign();
3603 .addAlignmentAttr(Alignment));
3604 uint64_t ArrSize = ArrTy->getZExtSize();
3608 Attrs.addDereferenceableAttr(
3609 getContext().getTypeSizeInChars(ETy).getQuantity() *
3611 AI->addAttrs(Attrs);
3612 }
else if (
getContext().getTargetInfo().getNullPointerValue(
3614 !
CGM.getCodeGenOpts().NullPointerIsValid) {
3615 AI->addAttr(llvm::Attribute::NonNull);
3618 }
else if (
const auto *ArrTy =
3624 QualType ETy = ArrTy->getElementType();
3625 llvm::Align Alignment =
3626 CGM.getNaturalTypeAlignment(ETy).getAsAlign();
3628 .addAlignmentAttr(Alignment));
3629 if (!
getTypes().getTargetAddressSpace(ETy) &&
3630 !
CGM.getCodeGenOpts().NullPointerIsValid)
3631 AI->addAttr(llvm::Attribute::NonNull);
3636 const auto *AVAttr = PVD->getAttr<AlignValueAttr>();
3639 AVAttr = TOTy->getDecl()->getAttr<AlignValueAttr>();
3640 if (AVAttr && !
SanOpts.has(SanitizerKind::Alignment)) {
3644 llvm::ConstantInt *AlignmentCI =
3646 uint64_t AlignmentInt =
3647 AlignmentCI->getLimitedValue(llvm::Value::MaximumAlignment);
3648 if (AI->getParamAlign().valueOrOne() < AlignmentInt) {
3649 AI->removeAttr(llvm::Attribute::AttrKind::Alignment);
3651 .addAlignmentAttr(llvm::Align(AlignmentInt)));
3658 AI->addAttr(llvm::Attribute::NoAlias);
3666 assert(NumIRArgs == 1);
3670 llvm::Value *
V = AI;
3678 V, pointeeTy,
getContext().getTypeAlignInChars(pointeeTy));
3679 llvm::Value *incomingErrorValue =
Builder.CreateLoad(arg);
3680 Builder.CreateStore(incomingErrorValue, temp);
3701 if (
V->getType() != LTy)
3712 if (
auto *VecTyTo = dyn_cast<llvm::FixedVectorType>(
ConvertType(Ty))) {
3713 llvm::Value *ArgVal = Fn->getArg(FirstIRArg);
3714 if (
auto *VecTyFrom =
3715 dyn_cast<llvm::ScalableVectorType>(ArgVal->getType())) {
3717 *
this, VecTyTo, VecTyFrom, ArgVal, Arg->
getName());
3719 assert(NumIRArgs == 1);
3726 llvm::StructType *STy =
3737 STy->getNumElements() > 1) {
3738 llvm::TypeSize StructSize =
CGM.getDataLayout().getTypeAllocSize(STy);
3739 llvm::TypeSize PtrElementSize =
3741 if (StructSize.isScalable()) {
3742 assert(STy->containsHomogeneousScalableVectorTypes() &&
3743 "ABI only supports structure with homogeneous scalable vector "
3745 assert(StructSize == PtrElementSize &&
3746 "Only allow non-fractional movement of structure with"
3747 "homogeneous scalable vector type");
3748 assert(STy->getNumElements() == NumIRArgs);
3750 llvm::Value *LoadedStructValue = llvm::PoisonValue::get(STy);
3751 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
3752 auto *AI = Fn->getArg(FirstIRArg + i);
3753 AI->setName(Arg->
getName() +
".coerce" + Twine(i));
3755 Builder.CreateInsertValue(LoadedStructValue, AI, i);
3758 Builder.CreateStore(LoadedStructValue, Ptr);
3760 uint64_t SrcSize = StructSize.getFixedValue();
3761 uint64_t DstSize = PtrElementSize.getFixedValue();
3764 if (SrcSize <= DstSize) {
3771 assert(STy->getNumElements() == NumIRArgs);
3772 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
3773 auto AI = Fn->getArg(FirstIRArg + i);
3774 AI->setName(Arg->
getName() +
".coerce" + Twine(i));
3776 Builder.CreateStore(AI, EltPtr);
3779 if (SrcSize > DstSize) {
3780 Builder.CreateMemCpy(Ptr, AddrToStoreInto, DstSize);
3792 assert(NumIRArgs == 1);
3793 auto AI = Fn->getArg(FirstIRArg);
3794 AI->setName(Arg->
getName() +
".coerce");
3797 llvm::TypeSize::getFixed(
3798 getContext().getTypeSizeInChars(Ty).getQuantity() -
3824 auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
3828 unsigned argIndex = FirstIRArg;
3829 unsigned unpaddedIndex = 0;
3830 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
3831 llvm::Type *eltType = coercionType->getElementType(i);
3835 auto eltAddr =
Builder.CreateStructGEP(alloca, i);
3836 llvm::Value *elt = Fn->getArg(argIndex++);
3838 auto paramType = unpaddedStruct
3839 ? unpaddedStruct->getElementType(unpaddedIndex++)
3840 : unpaddedCoercionType;
3842 if (
auto *VecTyTo = dyn_cast<llvm::FixedVectorType>(eltType)) {
3843 if (
auto *VecTyFrom = dyn_cast<llvm::ScalableVectorType>(paramType)) {
3846 *
this, VecTyTo, VecTyFrom, elt, elt->getName());
3847 assert(Extracted &&
"Unexpected scalable to fixed vector coercion");
3850 Builder.CreateStore(elt, eltAddr);
3852 assert(argIndex == FirstIRArg + NumIRArgs);
3865 auto FnArgIter = Fn->arg_begin() + FirstIRArg;
3866 ExpandTypeFromArgs(Ty, LV, FnArgIter);
3867 assert(FnArgIter == Fn->arg_begin() + FirstIRArg + NumIRArgs);
3868 for (
unsigned i = 0, e = NumIRArgs; i != e; ++i) {
3869 auto AI = Fn->getArg(FirstIRArg + i);
3870 AI->setName(Arg->
getName() +
"." + Twine(i));
3876 auto *AI = Fn->getArg(FirstIRArg);
3877 AI->setName(Arg->
getName() +
".target_coerce");
3881 CGM.getABIInfo().createCoercedStore(AI, Ptr, ArgI,
false, *
this);
3895 assert(NumIRArgs == 0);
3908 if (
getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) {
3909 for (
int I = Args.size() - 1; I >= 0; --I)
3912 for (
unsigned I = 0, E = Args.size(); I != E; ++I)
3918 while (insn->use_empty()) {
3919 llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(insn);
3925 bitcast->eraseFromParent();
3931 llvm::Value *result) {
3933 llvm::BasicBlock *BB = CGF.
Builder.GetInsertBlock();
3936 if (&BB->back() != result)
3939 llvm::Type *resultType = result->getType();
3948 while (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(generator)) {
3954 if (generator->getNextNode() != bitcast)
3957 InstsToKill.push_back(bitcast);
3964 llvm::CallInst *call = dyn_cast<llvm::CallInst>(generator);
3968 bool doRetainAutorelease;
3971 doRetainAutorelease =
true;
3972 }
else if (call->getCalledOperand() ==
3974 doRetainAutorelease =
false;
3982 llvm::Instruction *prev = call->getPrevNode();
3985 prev = prev->getPrevNode();
3991 InstsToKill.push_back(prev);
3997 result = call->getArgOperand(0);
3998 InstsToKill.push_back(call);
4002 while (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(result)) {
4003 if (!bitcast->hasOneUse())
4005 InstsToKill.push_back(bitcast);
4006 result = bitcast->getOperand(0);
4010 for (
auto *I : InstsToKill)
4011 I->eraseFromParent();
4014 if (doRetainAutorelease)
4018 return CGF.
Builder.CreateBitCast(result, resultType);
4023 llvm::Value *result) {
4026 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurCodeDecl);
4035 llvm::CallInst *retainCall = dyn_cast<llvm::CallInst>(result);
4036 if (!retainCall || retainCall->getCalledOperand() !=
4041 llvm::Value *retainedValue = retainCall->getArgOperand(0);
4042 llvm::LoadInst *load =
4043 dyn_cast<llvm::LoadInst>(retainedValue->stripPointerCasts());
4044 if (!load || load->isAtomic() || load->isVolatile() ||
4051 llvm::Type *resultType = result->getType();
4053 assert(retainCall->use_empty());
4054 retainCall->eraseFromParent();
4057 return CGF.
Builder.CreateBitCast(load, resultType);
4064 llvm::Value *result) {
4087 auto GetStoreIfValid = [&CGF,
4088 ReturnValuePtr](llvm::User *
U) -> llvm::StoreInst * {
4089 auto *SI = dyn_cast<llvm::StoreInst>(
U);
4090 if (!SI || SI->getPointerOperand() != ReturnValuePtr ||
4096 assert(!SI->isAtomic() &&
4104 if (!ReturnValuePtr->hasOneUse()) {
4105 llvm::BasicBlock *IP = CGF.
Builder.GetInsertBlock();
4111 const llvm::Instruction *LoadIntoFakeUse =
nullptr;
4112 for (llvm::Instruction &I : llvm::reverse(*IP)) {
4116 if (LoadIntoFakeUse == &I)
4120 if (
auto *II = dyn_cast<llvm::IntrinsicInst>(&I)) {
4121 if (II->getIntrinsicID() == llvm::Intrinsic::lifetime_end)
4124 if (II->getIntrinsicID() == llvm::Intrinsic::fake_use) {
4125 LoadIntoFakeUse = dyn_cast<llvm::Instruction>(II->getArgOperand(0));
4129 return GetStoreIfValid(&I);
4134 llvm::StoreInst *store = GetStoreIfValid(ReturnValuePtr->user_back());
4140 llvm::BasicBlock *StoreBB = store->getParent();
4141 llvm::BasicBlock *IP = CGF.
Builder.GetInsertBlock();
4143 while (IP != StoreBB) {
4144 if (!SeenBBs.insert(IP).second || !(IP = IP->getSinglePredecessor()))
4160 int BitWidth,
int CharWidth) {
4161 assert(CharWidth <= 64);
4162 assert(
static_cast<unsigned>(BitWidth) <= Bits.size() * CharWidth);
4165 if (BitOffset >= CharWidth) {
4166 Pos += BitOffset / CharWidth;
4167 BitOffset = BitOffset % CharWidth;
4170 const uint64_t
Used = (uint64_t(1) << CharWidth) - 1;
4171 if (BitOffset + BitWidth >= CharWidth) {
4172 Bits[Pos++] |= (
Used << BitOffset) &
Used;
4173 BitWidth -= CharWidth - BitOffset;
4177 while (BitWidth >= CharWidth) {
4179 BitWidth -= CharWidth;
4183 Bits[Pos++] |= (
Used >> (CharWidth - BitWidth)) << BitOffset;
4191 int StorageSize,
int BitOffset,
int BitWidth,
4192 int CharWidth,
bool BigEndian) {
4195 setBitRange(TmpBits, BitOffset, BitWidth, CharWidth);
4198 std::reverse(TmpBits.begin(), TmpBits.end());
4200 for (uint64_t
V : TmpBits)
4201 Bits[StorageOffset++] |=
V;
4204static void setUsedBits(CodeGenModule &, QualType,
int,
4205 SmallVectorImpl<uint64_t> &);
4247 QualType ETy = Context.getBaseElementType(ATy);
4248 int Size = Context.getTypeSizeInChars(ETy).getQuantity();
4252 for (
int I = 0, N = Context.getConstantArrayElementCount(ATy); I < N; ++I) {
4253 auto Src = TmpBits.begin();
4254 auto Dst = Bits.begin() + Offset + I * Size;
4255 for (
int J = 0; J < Size; ++J)
4268 if (
const auto *ATy = Context.getAsConstantArrayType(QTy))
4271 int Size = Context.getTypeSizeInChars(QTy).getQuantity();
4275 std::fill_n(Bits.begin() + Offset, Size,
4276 (uint64_t(1) << Context.getCharWidth()) - 1);
4280 int Pos,
int Size,
int CharWidth,
4285 for (
auto P = Bits.begin() + Pos, E = Bits.begin() + Pos + Size; P != E;
4287 Mask = (Mask << CharWidth) | *P;
4289 auto P = Bits.begin() + Pos + Size, End = Bits.begin() + Pos;
4291 Mask = (Mask << CharWidth) | *--P;
4300 llvm::IntegerType *ITy,
4302 assert(Src->getType() == ITy);
4303 assert(ITy->getScalarSizeInBits() <= 64);
4305 const llvm::DataLayout &DataLayout =
CGM.getDataLayout();
4306 int Size = DataLayout.getTypeStoreSize(ITy);
4310 int CharWidth =
CGM.getContext().getCharWidth();
4314 return Builder.CreateAnd(Src, Mask,
"cmse.clear");
4320 llvm::ArrayType *ATy,
4322 const llvm::DataLayout &DataLayout =
CGM.getDataLayout();
4323 int Size = DataLayout.getTypeStoreSize(ATy);
4328 int CharWidth =
CGM.getContext().getCharWidth();
4330 ATy->getArrayElementType()->getScalarSizeInBits() / CharWidth;
4332 llvm::Value *R = llvm::PoisonValue::get(ATy);
4333 for (
int I = 0, N = ATy->getArrayNumElements(); I != N; ++I) {
4335 DataLayout.isBigEndian());
4336 MaskIndex += CharsPerElt;
4337 llvm::Value *T0 =
Builder.CreateExtractValue(Src, I);
4338 llvm::Value *T1 =
Builder.CreateAnd(T0, Mask,
"cmse.clear");
4339 R =
Builder.CreateInsertValue(R, T1, I);
4347 uint64_t RetKeyInstructionsSourceAtom) {
4362 auto *I =
Builder.CreateRetVoid();
4363 if (RetKeyInstructionsSourceAtom)
4370 llvm::DebugLoc RetDbgLoc;
4371 llvm::Value *RV =
nullptr;
4381 llvm::Function::arg_iterator EI =
CurFn->arg_end();
4383 llvm::Value *ArgStruct = &*EI;
4384 llvm::Value *SRet =
Builder.CreateStructGEP(
4393 auto AI =
CurFn->arg_begin();
4411 CGM.getNaturalTypeAlignment(RetTy, &BaseInfo, &TBAAInfo);
4438 RetDbgLoc = SI->getDebugLoc();
4440 RV = SI->getValueOperand();
4441 SI->eraseFromParent();
4464 if (
auto *FD = dyn_cast<FunctionDecl>(
CurCodeDecl))
4465 RT = FD->getReturnType();
4466 else if (
auto *MD = dyn_cast<ObjCMethodDecl>(
CurCodeDecl))
4467 RT = MD->getReturnType();
4469 RT =
BlockInfo->BlockExpression->getFunctionType()->getReturnType();
4471 llvm_unreachable(
"Unexpected function/method type");
4487 auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
4492 unsigned unpaddedIndex = 0;
4493 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
4494 auto coercedEltType = coercionType->getElementType(i);
4498 auto eltAddr =
Builder.CreateStructGEP(addr, i);
4501 unpaddedStruct ? unpaddedStruct->getElementType(unpaddedIndex++)
4502 : unpaddedCoercionType,
4504 results.push_back(elt);
4508 if (results.size() == 1) {
4516 RV = llvm::PoisonValue::get(returnType);
4517 for (
unsigned i = 0, e = results.size(); i != e; ++i) {
4518 RV =
Builder.CreateInsertValue(RV, results[i], i);
4525 RV =
CGM.getABIInfo().createCoercedLoad(
V, RetAI, *
this);
4530 llvm_unreachable(
"Invalid ABI kind for return argument");
4533 llvm::Instruction *Ret;
4539 auto *ITy = dyn_cast<llvm::IntegerType>(RV->getType());
4546 Ret =
Builder.CreateRetVoid();
4550 Ret->setDebugLoc(std::move(RetDbgLoc));
4552 llvm::Value *Backup = RV ? Ret->getOperand(0) :
nullptr;
4553 if (RetKeyInstructionsSourceAtom)
4569 ReturnsNonNullAttr *RetNNAttr =
nullptr;
4570 if (
SanOpts.has(SanitizerKind::ReturnsNonnullAttribute))
4571 RetNNAttr =
CurCodeDecl->getAttr<ReturnsNonNullAttr>();
4573 if (!RetNNAttr && !requiresReturnValueNullabilityCheck())
4581 assert(!requiresReturnValueNullabilityCheck() &&
4582 "Cannot check nullability and the nonnull attribute");
4583 AttrLoc = RetNNAttr->getLocation();
4584 CheckKind = SanitizerKind::SO_ReturnsNonnullAttribute;
4585 Handler = SanitizerHandler::NonnullReturn;
4587 if (
auto *DD = dyn_cast<DeclaratorDecl>(
CurCodeDecl))
4588 if (
auto *TSI = DD->getTypeSourceInfo())
4590 AttrLoc = FTL.getReturnLoc().findNullabilityLoc();
4591 CheckKind = SanitizerKind::SO_NullabilityReturn;
4592 Handler = SanitizerHandler::NullabilityReturn;
4601 llvm::Value *SLocPtr =
Builder.CreateLoad(ReturnLocation,
"return.sloc.load");
4602 llvm::Value *CanNullCheck =
Builder.CreateIsNotNull(SLocPtr);
4603 if (requiresReturnValueNullabilityCheck())
4605 Builder.CreateAnd(CanNullCheck, RetValNullabilityPrecondition);
4606 Builder.CreateCondBr(CanNullCheck, Check, NoCheck);
4612 llvm::Value *DynamicData[] = {SLocPtr};
4613 EmitCheck(std::make_pair(
Cond, CheckKind), Handler, StaticData, DynamicData);
4632 llvm::Type *IRPtrTy = llvm::PointerType::getUnqual(CGF.
getLLVMContext());
4633 llvm::Value *Placeholder = llvm::PoisonValue::get(IRPtrTy);
4658 if (
type->isReferenceType()) {
4667 param->
hasAttr<NSConsumedAttr>() &&
type->isObjCRetainableType()) {
4668 llvm::Value *ptr =
Builder.CreateLoad(local);
4671 Builder.CreateStore(null, local);
4682 type->castAsRecordDecl()->isParamDestroyedInCallee() &&
4687 "cleanup for callee-destructed param not recorded");
4689 llvm::Instruction *isActive =
Builder.CreateUnreachable();
4695 return llvm::isa_and_nonnull<llvm::ConstantPointerNull>(addr);
4705 const LValue &srcLV = writeback.
Source;
4706 Address srcAddr = srcLV.getAddress();
4708 "shouldn't have writeback for provably null argument");
4716 llvm::BasicBlock *contBB =
nullptr;
4722 if (!provablyNonNull) {
4727 CGF.
Builder.CreateCondBr(isNull, contBB, writebackBB);
4736 "icr.writeback-cast");
4745 if (writeback.
ToUse) {
4770 if (!provablyNonNull)
4779 for (
const auto &I : llvm::reverse(Cleanups)) {
4781 I.IsActiveIP->eraseFromParent();
4787 if (uop->getOpcode() == UO_AddrOf)
4788 return uop->getSubExpr();
4813 Address srcAddr = srcLV.getAddress();
4818 llvm::PointerType *destType =
4820 llvm::Type *destElemType =
4847 llvm::BasicBlock *contBB =
nullptr;
4848 llvm::BasicBlock *originBB =
nullptr;
4851 llvm::Value *finalArgument;
4855 if (provablyNonNull) {
4860 finalArgument = CGF.
Builder.CreateSelect(
4861 isNull, llvm::ConstantPointerNull::get(destType),
4867 originBB = CGF.
Builder.GetInsertBlock();
4870 CGF.
Builder.CreateCondBr(isNull, contBB, copyBB);
4872 condEval.
begin(CGF);
4876 llvm::Value *valueToUse =
nullptr;
4884 src = CGF.
Builder.CreateBitCast(src, destElemType,
"icr.cast");
4901 if (shouldCopy && !provablyNonNull) {
4902 llvm::BasicBlock *copyBB = CGF.
Builder.GetInsertBlock();
4907 llvm::PHINode *phiToUse =
4908 CGF.
Builder.CreatePHI(valueToUse->getType(), 2,
"icr.to-use");
4909 phiToUse->addIncoming(valueToUse, copyBB);
4910 phiToUse->addIncoming(llvm::PoisonValue::get(valueToUse->getType()),
4912 valueToUse = phiToUse;
4926 StackBase = CGF.
Builder.CreateStackSave(
"inalloca.save");
4932 CGF.
Builder.CreateStackRestore(StackBase);
4939 if (!AC.
getDecl() || !(
SanOpts.has(SanitizerKind::NonnullAttribute) ||
4940 SanOpts.has(SanitizerKind::NullabilityArg)))
4945 unsigned ArgNo = PVD ? PVD->getFunctionScopeIndex() : ParmNum;
4948 const NonNullAttr *NNAttr =
nullptr;
4949 if (
SanOpts.has(SanitizerKind::NonnullAttribute))
4952 bool CanCheckNullability =
false;
4953 if (
SanOpts.has(SanitizerKind::NullabilityArg) && !NNAttr && PVD &&
4954 !PVD->getType()->isRecordType()) {
4955 auto Nullability = PVD->getType()->getNullability();
4956 CanCheckNullability = Nullability &&
4958 PVD->getTypeSourceInfo();
4961 if (!NNAttr && !CanCheckNullability)
4968 AttrLoc = NNAttr->getLocation();
4969 CheckKind = SanitizerKind::SO_NonnullAttribute;
4970 Handler = SanitizerHandler::NonnullArg;
4972 AttrLoc = PVD->getTypeSourceInfo()->getTypeLoc().findNullabilityLoc();
4973 CheckKind = SanitizerKind::SO_NullabilityArg;
4974 Handler = SanitizerHandler::NullabilityArg;
4979 llvm::Constant *StaticData[] = {
4982 llvm::ConstantInt::get(
Int32Ty, ArgNo + 1),
4984 EmitCheck(std::make_pair(
Cond, CheckKind), Handler, StaticData, {});
4990 if (!AC.
getDecl() || !(
SanOpts.has(SanitizerKind::NonnullAttribute) ||
4991 SanOpts.has(SanitizerKind::NullabilityArg)))
5010 return llvm::any_of(ArgTypes, [&](
QualType Ty) {
5021 return classDecl->getTypeParamListAsWritten();
5025 return catDecl->getTypeParamList();
5035 llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
5039 assert((ParamsToSkip == 0 ||
Prototype.P) &&
5040 "Can't skip parameters if type info is not provided");
5050 bool IsVariadic =
false;
5052 const auto *MD = dyn_cast<const ObjCMethodDecl *>(
Prototype.P);
5054 IsVariadic = MD->isVariadic();
5056 MD,
CGM.getTarget().getTriple().isOSWindows());
5057 ArgTypes.assign(MD->param_type_begin() + ParamsToSkip,
5058 MD->param_type_end());
5061 IsVariadic = FPT->isVariadic();
5062 ExplicitCC = FPT->getExtInfo().getCC();
5063 ArgTypes.assign(FPT->param_type_begin() + ParamsToSkip,
5064 FPT->param_type_end());
5072 assert(Arg != ArgRange.end() &&
"Running over edge of argument list!");
5074 QualType ArgTy = (*Arg)->getType();
5075 if (
const auto *OBT = ParamTy->
getAs<OverflowBehaviorType>())
5076 ParamTy = OBT->getUnderlyingType();
5077 if (
const auto *OBT = ArgTy->
getAs<OverflowBehaviorType>())
5078 ArgTy = OBT->getUnderlyingType();
5081 getContext().getCanonicalType(ParamTy).getTypePtr() ==
5082 getContext().getCanonicalType(ArgTy).getTypePtr()) &&
5083 "type mismatch in call argument!");
5089 assert((Arg == ArgRange.end() || IsVariadic) &&
5090 "Extra arguments in non-variadic function!");
5095 for (
auto *A : llvm::drop_begin(ArgRange, ArgTypes.size()))
5096 ArgTypes.push_back(IsVariadic ? getVarArgType(A) : A->getType());
5097 assert((
int)ArgTypes.size() == (ArgRange.end() - ArgRange.begin()));
5105 CGM.getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()
5109 auto MaybeEmitImplicitObjectSize = [&](
unsigned I,
const Expr *Arg,
5118 auto SizeTy = Context.getSizeType();
5120 assert(EmittedArg.getScalarVal() &&
"We emitted nothing for the arg?");
5121 llvm::Value *
V = evaluateOrEmitBuiltinObjectSize(
5122 Arg, PS->getType(),
T, EmittedArg.getScalarVal(), PS->isDynamic());
5127 std::swap(Args.back(), *(&Args.back() - 1));
5133 "inalloca only supported on x86");
5138 size_t CallArgsStart = Args.size();
5139 for (
unsigned I = 0, E = ArgTypes.size(); I != E; ++I) {
5140 unsigned Idx = LeftToRight ? I : E - I - 1;
5142 unsigned InitialArgSize = Args.size();
5146 getContext().hasSameUnqualifiedType((*Arg)->getType(),
5150 "Argument and parameter types don't match");
5154 assert(InitialArgSize + 1 == Args.size() &&
5155 "The code below depends on only adding one arg per EmitCallArg");
5156 (void)InitialArgSize;
5159 if (!Args.back().hasLValue()) {
5160 RValue RVArg = Args.back().getKnownRValue();
5162 ParamsToSkip + Idx);
5166 MaybeEmitImplicitObjectSize(Idx, *Arg, RVArg);
5173 std::reverse(Args.begin() + CallArgsStart, Args.end());
5182struct DestroyUnpassedArg final : EHScopeStack::Cleanup {
5192 assert(!Dtor->isTrivial());
5215 if (!HasLV &&
RV.isScalar())
5217 else if (!HasLV &&
RV.isComplex())
5220 auto Addr = HasLV ?
LV.getAddress() :
RV.getAggregateAddress();
5224 HasLV ?
LV.isVolatileQualified()
5225 :
RV.isVolatileQualified());
5237 std::optional<DisableDebugLocationUpdates> Dis;
5241 dyn_cast<ObjCIndirectCopyRestoreExpr>(E)) {
5255 "reference binding to unmaterialized r-value!");
5267 if (
type->isRecordType() &&
5268 type->castAsRecordDecl()->isParamDestroyedInCallee()) {
5275 bool DestroyedInCallee =
true, NeedsCleanup =
true;
5276 if (
const auto *RD =
type->getAsCXXRecordDecl())
5277 DestroyedInCallee = RD->hasNonTrivialDestructor();
5279 NeedsCleanup =
type.isDestructedType();
5281 if (DestroyedInCallee)
5288 if (DestroyedInCallee && NeedsCleanup) {
5295 llvm::Instruction *IsActive =
5302 if (HasAggregateEvalKind) {
5303 auto *ICE = dyn_cast<ImplicitCastExpr>(E);
5304 if (ICE && ICE->getCastKind() == CK_LValueToRValue &&
5305 ICE->getSubExpr()->getType().getAddressSpace() !=
5307 !
type->isArrayParameterType() && !
type.isNonTrivialToPrimitiveCopy()) {
5318QualType CodeGenFunction::getVarArgType(
const Expr *Arg) {
5322 if (!getTarget().
getTriple().isOSWindows())
5326 getContext().getTypeSize(Arg->
getType()) <
5330 return getContext().getIntPtrType();
5338void CodeGenFunction::AddObjCARCExceptionMetadata(llvm::Instruction *Inst) {
5339 if (CGM.getCodeGenOpts().OptimizationLevel != 0 &&
5340 !CGM.getCodeGenOpts().ObjCAutoRefCountExceptions)
5341 Inst->setMetadata(
"clang.arc.no_objc_arc_exceptions",
5342 CGM.getNoObjCARCExceptionsMetadata());
5348 const llvm::Twine &name) {
5349 return EmitNounwindRuntimeCall(callee, ArrayRef<llvm::Value *>(), name);
5355 ArrayRef<Address> args,
5356 const llvm::Twine &name) {
5357 SmallVector<llvm::Value *, 3> values;
5358 for (
auto arg : args)
5359 values.push_back(
arg.emitRawPointer(*
this));
5360 return EmitNounwindRuntimeCall(callee, values, name);
5365 ArrayRef<llvm::Value *> args,
5366 const llvm::Twine &name) {
5367 llvm::CallInst *call = EmitRuntimeCall(callee, args, name);
5368 call->setDoesNotThrow();
5375 const llvm::Twine &name) {
5376 return EmitRuntimeCall(callee, {},
name);
5381SmallVector<llvm::OperandBundleDef, 1>
5390 if (
auto *CalleeFn = dyn_cast<llvm::Function>(Callee->stripPointerCasts())) {
5391 if (CalleeFn->isIntrinsic() && CalleeFn->doesNotThrow()) {
5392 auto IID = CalleeFn->getIntrinsicID();
5393 if (!llvm::IntrinsicInst::mayLowerToFunctionCall(IID))
5406 const llvm::Twine &name) {
5407 llvm::CallInst *call = Builder.CreateCall(
5408 callee, args, getBundlesForFunclet(callee.getCallee()), name);
5409 call->setCallingConv(getRuntimeCC());
5411 if (CGM.shouldEmitConvergenceTokens() && call->isConvergent())
5417 const llvm::Twine &Name) {
5418 return EmitIntrinsicCall(ID, {}, {}, Name);
5422 ArrayRef<llvm::Value *> Args,
5423 const llvm::Twine &Name) {
5424 return EmitIntrinsicCall(ID, {}, Args, Name);
5428 ArrayRef<llvm::Type *> Types,
5429 ArrayRef<llvm::Value *> Args,
5430 const llvm::Twine &Name) {
5432 llvm::Intrinsic::getOrInsertDeclaration(&CGM.getModule(), ID, Types);
5433 llvm::CallInst *
Call =
5434 Builder.CreateCall(F, Args, getBundlesForFunclet(F), Name);
5435 if (CGM.shouldEmitConvergenceTokens() &&
Call->isConvergent())
5447 llvm::InvokeInst *invoke =
Builder.CreateInvoke(
5449 invoke->setDoesNotReturn();
5452 llvm::CallInst *call =
Builder.CreateCall(callee, args, BundleList);
5453 call->setDoesNotReturn();
5462 const Twine &name) {
5470 const Twine &name) {
5480 const Twine &Name) {
5485 llvm::CallBase *Inst;
5487 Inst =
Builder.CreateCall(Callee, Args, BundleList, Name);
5490 Inst =
Builder.CreateInvoke(Callee, ContBB, InvokeDest, Args, BundleList,
5497 if (
CGM.getLangOpts().ObjCAutoRefCount)
5498 AddObjCARCExceptionMetadata(Inst);
5503void CodeGenFunction::deferPlaceholderReplacement(llvm::Instruction *Old,
5505 DeferredReplacements.push_back(
5506 std::make_pair(llvm::WeakTrackingVH(Old),
New));
5513[[nodiscard]] llvm::AttributeList
5514maybeRaiseRetAlignmentAttribute(llvm::LLVMContext &Ctx,
5515 const llvm::AttributeList &Attrs,
5516 llvm::Align NewAlign) {
5517 llvm::Align CurAlign = Attrs.getRetAlignment().valueOrOne();
5518 if (CurAlign >= NewAlign)
5520 llvm::Attribute AlignAttr = llvm::Attribute::getWithAlignment(Ctx, NewAlign);
5521 return Attrs.removeRetAttribute(Ctx, llvm::Attribute::AttrKind::Alignment)
5522 .addRetAttribute(Ctx, AlignAttr);
5525template <
typename AlignedAttrTy>
class AbstractAssumeAlignedAttrEmitter {
5530 const AlignedAttrTy *AA =
nullptr;
5532 llvm::Value *Alignment =
nullptr;
5533 llvm::ConstantInt *OffsetCI =
nullptr;
5539 AA = FuncDecl->
getAttr<AlignedAttrTy>();
5544 [[nodiscard]] llvm::AttributeList
5545 TryEmitAsCallSiteAttribute(
const llvm::AttributeList &Attrs) {
5546 if (!AA || OffsetCI || CGF.
SanOpts.
has(SanitizerKind::Alignment))
5548 const auto *AlignmentCI = dyn_cast<llvm::ConstantInt>(Alignment);
5553 if (!AlignmentCI->getValue().isPowerOf2())
5555 llvm::AttributeList NewAttrs = maybeRaiseRetAlignmentAttribute(
5558 AlignmentCI->getLimitedValue(llvm::Value::MaximumAlignment)));
5566 void EmitAsAnAssumption(SourceLocation Loc, QualType RetTy, RValue &Ret) {
5570 AA->getLocation(), Alignment, OffsetCI);
5576class AssumeAlignedAttrEmitter final
5577 :
public AbstractAssumeAlignedAttrEmitter<AssumeAlignedAttr> {
5579 AssumeAlignedAttrEmitter(CodeGenFunction &CGF_,
const Decl *FuncDecl)
5580 : AbstractAssumeAlignedAttrEmitter(CGF_, FuncDecl) {
5585 if (Expr *Offset = AA->getOffset()) {
5587 if (OffsetCI->isNullValue())
5594class AllocAlignAttrEmitter final
5595 :
public AbstractAssumeAlignedAttrEmitter<AllocAlignAttr> {
5597 AllocAlignAttrEmitter(CodeGenFunction &CGF_,
const Decl *FuncDecl,
5598 const CallArgList &CallArgs)
5599 : AbstractAssumeAlignedAttrEmitter(CGF_, FuncDecl) {
5603 Alignment = CallArgs[AA->getParamIndex().getLLVMIndex()]
5612 if (
auto *VT = dyn_cast<llvm::VectorType>(Ty))
5613 return VT->getPrimitiveSizeInBits().getKnownMinValue();
5614 if (
auto *AT = dyn_cast<llvm::ArrayType>(Ty))
5617 unsigned MaxVectorWidth = 0;
5618 if (
auto *ST = dyn_cast<llvm::StructType>(Ty))
5619 for (
auto *I : ST->elements())
5621 return MaxVectorWidth;
5628 llvm::CallBase **callOrInvoke,
bool IsMustTail,
5630 bool IsVirtualFunctionPointerThunk) {
5633 assert(Callee.isOrdinary() || Callee.isVirtual());
5640 llvm::FunctionType *IRFuncTy =
getTypes().GetFunctionType(CallInfo);
5642 const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl().getDecl();
5643 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
5650 if ((TargetDecl->
hasAttr<AlwaysInlineAttr>() &&
5651 (TargetDecl->
hasAttr<TargetAttr>() ||
5655 TargetDecl->
hasAttr<TargetAttr>())))
5662 const FunctionDecl *CalleeDecl = dyn_cast_or_null<FunctionDecl>(TargetDecl);
5663 CGM.getTargetCodeGenInfo().checkFunctionCallABI(
CGM, Loc, CallerDecl,
5664 CalleeDecl, CallArgs, RetTy);
5671 if (llvm::StructType *ArgStruct = CallInfo.
getArgStruct()) {
5672 const llvm::DataLayout &DL =
CGM.getDataLayout();
5674 llvm::AllocaInst *AI;
5676 IP = IP->getNextNode();
5677 AI =
new llvm::AllocaInst(ArgStruct, DL.getAllocaAddrSpace(),
"argmem",
5683 AI->setAlignment(Align.getAsAlign());
5684 AI->setUsedWithInAlloca(
true);
5685 assert(AI->isUsedWithInAlloca() && !AI->isStaticAlloca());
5686 ArgMemory =
RawAddress(AI, ArgStruct, Align);
5689 ClangToLLVMArgMapping IRFunctionArgs(
CGM.getContext(), CallInfo);
5697 bool NeedSRetLifetimeEnd =
false;
5703 if ((IsVirtualFunctionPointerThunk || IsMustTail) && RetAI.
isIndirect()) {
5705 IRFunctionArgs.getSRetArgNo(),
5713 if (NeedSRetLifetimeEnd)
5714 SRetAlloca = SRetPtr;
5717 if (IRFunctionArgs.hasSRetArg()) {
5730 IRCallArgs[IRFunctionArgs.getSRetArgNo()] =
5748 assert(CallInfo.
arg_size() == CallArgs.size() &&
5749 "Mismatch between function signature & arguments.");
5752 for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end();
5753 I != E; ++I, ++info_it, ++ArgNo) {
5757 if (IRFunctionArgs.hasPaddingArg(ArgNo))
5758 IRCallArgs[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
5761 unsigned FirstIRArg, NumIRArgs;
5762 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
5764 bool ArgHasMaybeUndefAttr =
5769 assert(NumIRArgs == 0);
5771 if (I->isAggregate()) {
5773 ? I->getKnownLValue().getAddress()
5774 : I->getKnownRValue().getAggregateAddress();
5775 llvm::Instruction *Placeholder =
5780 CGBuilderTy::InsertPoint IP =
Builder.saveIP();
5781 Builder.SetInsertPoint(Placeholder);
5795 deferPlaceholderReplacement(Placeholder,
Addr.getPointer());
5800 I->Ty,
getContext().getTypeAlignInChars(I->Ty),
5801 "indirect-arg-temp");
5802 I->copyInto(*
this,
Addr);
5811 I->copyInto(*
this,
Addr);
5818 assert(NumIRArgs == 1);
5819 if (I->isAggregate()) {
5829 ? I->getKnownLValue().getAddress()
5830 : I->getKnownRValue().getAggregateAddress();
5832 const llvm::DataLayout *TD = &
CGM.getDataLayout();
5834 assert((FirstIRArg >= IRFuncTy->getNumParams() ||
5835 IRFuncTy->getParamType(FirstIRArg)->getPointerAddressSpace() ==
5836 TD->getAllocaAddrSpace()) &&
5837 "indirect argument must be in alloca address space");
5839 bool NeedCopy =
false;
5840 if (
Addr.getAlignment() < Align &&
5841 llvm::getOrEnforceKnownAlignment(
Addr.emitRawPointer(*
this),
5845 }
else if (I->hasLValue()) {
5846 auto LV = I->getKnownLValue();
5851 if (!isByValOrRef ||
5852 (LV.getAlignment() <
getContext().getTypeAlignInChars(I->Ty))) {
5856 if (isByValOrRef &&
Addr.getType()->getAddressSpace() !=
5865 auto *
T = llvm::PointerType::get(
CGM.getLLVMContext(),
5873 if (ArgHasMaybeUndefAttr)
5874 Val =
Builder.CreateFreeze(Val);
5875 IRCallArgs[FirstIRArg] = Val;
5878 }
else if (I->getType()->isArrayParameterType()) {
5884 IRCallArgs[FirstIRArg] = I->getKnownRValue().getScalarVal();
5893 if (ArgHasMaybeUndefAttr)
5894 Val =
Builder.CreateFreeze(Val);
5895 IRCallArgs[FirstIRArg] = Val;
5900 CallLifetimeEndAfterCall.emplace_back(AI);
5903 I->copyInto(*
this, AI);
5908 assert(NumIRArgs == 0);
5916 assert(NumIRArgs == 1);
5918 if (!I->isAggregate())
5919 V = I->getKnownRValue().getScalarVal();
5922 I->hasLValue() ? I->getKnownLValue().getAddress()
5923 : I->getKnownRValue().getAggregateAddress());
5929 assert(!swiftErrorTemp.
isValid() &&
"multiple swifterror args");
5933 V, pointeeTy,
getContext().getTypeAlignInChars(pointeeTy));
5940 llvm::Value *errorValue =
Builder.CreateLoad(swiftErrorArg);
5941 Builder.CreateStore(errorValue, swiftErrorTemp);
5946 V->getType()->isIntegerTy())
5953 if (FirstIRArg < IRFuncTy->getNumParams() &&
5954 V->getType() != IRFuncTy->getParamType(FirstIRArg)) {
5955 assert(
V->getType()->isPointerTy() &&
"Only pointers can mismatch!");
5959 if (ArgHasMaybeUndefAttr)
5961 IRCallArgs[FirstIRArg] =
V;
5965 llvm::StructType *STy =
5970 if (!I->isAggregate()) {
5972 I->copyInto(*
this, Src);
5974 Src = I->hasLValue() ? I->getKnownLValue().getAddress()
5975 : I->getKnownRValue().getAggregateAddress();
5985 llvm::TypeSize SrcTypeSize =
5986 CGM.getDataLayout().getTypeAllocSize(SrcTy);
5987 llvm::TypeSize DstTypeSize =
CGM.getDataLayout().getTypeAllocSize(STy);
5988 if (SrcTypeSize.isScalable()) {
5989 assert(STy->containsHomogeneousScalableVectorTypes() &&
5990 "ABI only supports structure with homogeneous scalable vector "
5992 assert(SrcTypeSize == DstTypeSize &&
5993 "Only allow non-fractional movement of structure with "
5994 "homogeneous scalable vector type");
5995 assert(NumIRArgs == STy->getNumElements());
5997 llvm::Value *StoredStructValue =
5999 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
6000 llvm::Value *Extract =
Builder.CreateExtractValue(
6001 StoredStructValue, i, Src.
getName() +
".extract" + Twine(i));
6002 IRCallArgs[FirstIRArg + i] = Extract;
6005 uint64_t SrcSize = SrcTypeSize.getFixedValue();
6006 uint64_t DstSize = DstTypeSize.getFixedValue();
6007 bool HasPFPFields =
getContext().hasPFPFields(I->Ty);
6013 if (HasPFPFields || SrcSize < DstSize) {
6024 Builder.CreateMemCpy(TempAlloca, Src, SrcSize);
6030 assert(NumIRArgs == STy->getNumElements());
6031 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
6033 llvm::Value *LI =
Builder.CreateLoad(EltPtr);
6034 if (ArgHasMaybeUndefAttr)
6035 LI =
Builder.CreateFreeze(LI);
6036 IRCallArgs[FirstIRArg + i] = LI;
6041 assert(NumIRArgs == 1);
6049 auto *ATy = dyn_cast<llvm::ArrayType>(Load->getType());
6054 if (ArgHasMaybeUndefAttr)
6055 Load =
Builder.CreateFreeze(Load);
6056 IRCallArgs[FirstIRArg] = Load;
6064 auto layout =
CGM.getDataLayout().getStructLayout(coercionType);
6066 auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
6070 bool NeedLifetimeEnd =
false;
6071 if (I->isAggregate()) {
6072 addr = I->hasLValue() ? I->getKnownLValue().getAddress()
6073 : I->getKnownRValue().getAggregateAddress();
6076 RValue RV = I->getKnownRValue();
6080 auto scalarAlign =
CGM.getDataLayout().getPrefTypeAlign(scalarType);
6085 layout->getAlignment(), scalarAlign)),
6087 nullptr, &AllocaAddr);
6095 unsigned IRArgPos = FirstIRArg;
6096 unsigned unpaddedIndex = 0;
6097 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
6098 llvm::Type *eltType = coercionType->getElementType(i);
6105 : unpaddedCoercionType,
6107 if (ArgHasMaybeUndefAttr)
6108 elt =
Builder.CreateFreeze(elt);
6109 IRCallArgs[IRArgPos++] = elt;
6111 assert(IRArgPos == FirstIRArg + NumIRArgs);
6113 if (NeedLifetimeEnd)
6119 unsigned IRArgPos = FirstIRArg;
6120 ExpandTypeToArgs(I->Ty, *I, IRFuncTy, IRCallArgs, IRArgPos);
6121 assert(IRArgPos == FirstIRArg + NumIRArgs);
6127 if (!I->isAggregate()) {
6129 I->copyInto(*
this, Src);
6131 Src = I->hasLValue() ? I->getKnownLValue().getAddress()
6132 : I->getKnownRValue().getAggregateAddress();
6138 CGM.getABIInfo().createCoercedLoad(Src, ArgInfo, *
this);
6139 IRCallArgs[FirstIRArg] = Load;
6145 const CGCallee &ConcreteCallee = Callee.prepareConcreteCallee(*
this);
6151 assert(IRFunctionArgs.hasInallocaArg());
6152 IRCallArgs[IRFunctionArgs.getInallocaArgNo()] = Arg;
6163 auto simplifyVariadicCallee = [](llvm::FunctionType *CalleeFT,
6164 llvm::Value *Ptr) -> llvm::Function * {
6165 if (!CalleeFT->isVarArg())
6169 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Ptr)) {
6170 if (CE->getOpcode() == llvm::Instruction::BitCast)
6171 Ptr = CE->getOperand(0);
6174 llvm::Function *OrigFn = dyn_cast<llvm::Function>(Ptr);
6178 llvm::FunctionType *OrigFT = OrigFn->getFunctionType();
6182 if (OrigFT->isVarArg() ||
6183 OrigFT->getNumParams() != CalleeFT->getNumParams() ||
6184 OrigFT->getReturnType() != CalleeFT->getReturnType())
6187 for (
unsigned i = 0, e = OrigFT->getNumParams(); i != e; ++i)
6188 if (OrigFT->getParamType(i) != CalleeFT->getParamType(i))
6194 if (llvm::Function *OrigFn = simplifyVariadicCallee(IRFuncTy, CalleePtr)) {
6196 IRFuncTy = OrigFn->getFunctionType();
6207 for (
unsigned i = 0; i < IRCallArgs.size(); ++i)
6208 LargestVectorWidth = std::max(LargestVectorWidth,
6213 llvm::AttributeList Attrs;
6214 CGM.ConstructAttributeList(CalleePtr->getName(), CallInfo,
6219 if (
CallingConv == llvm::CallingConv::X86_VectorCall &&
6221 CGM.Error(Loc,
"__vectorcall calling convention is not currently "
6226 if (FD->hasAttr<StrictFPAttr>())
6228 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::StrictFP);
6233 if (FD->hasAttr<OptimizeNoneAttr>() &&
getLangOpts().FastMath)
6234 CGM.AdjustMemoryAttribute(CalleePtr->getName(), Callee.getAbstractInfo(),
6239 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::NoMerge);
6243 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::NoInline);
6248 !
CGM.getTargetCodeGenInfo().wouldInliningViolateFunctionCallABI(
6249 CallerDecl, CalleeDecl))
6251 Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::AlwaysInline);
6256 Attrs.removeFnAttribute(
getLLVMContext(), llvm::Attribute::Convergent);
6265 !(TargetDecl && TargetDecl->
hasAttr<NoInlineAttr>()) &&
6266 !
CGM.getTargetCodeGenInfo().wouldInliningViolateFunctionCallABI(
6267 CallerDecl, CalleeDecl)) {
6269 Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::AlwaysInline);
6274 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::NoInline);
6281 CannotThrow =
false;
6290 CannotThrow = Attrs.hasFnAttr(llvm::Attribute::NoUnwind);
6292 if (
auto *FPtr = dyn_cast<llvm::Function>(CalleePtr))
6293 if (FPtr->hasFnAttribute(llvm::Attribute::NoUnwind))
6304 if (NeedSRetLifetimeEnd)
6312 if (
SanOpts.has(SanitizerKind::KCFI) &&
6313 !isa_and_nonnull<FunctionDecl>(TargetDecl))
6320 if (FD->hasAttr<StrictFPAttr>())
6322 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::StrictFP);
6324 AssumeAlignedAttrEmitter AssumeAlignedAttrEmitter(*
this, TargetDecl);
6325 Attrs = AssumeAlignedAttrEmitter.TryEmitAsCallSiteAttribute(Attrs);
6327 AllocAlignAttrEmitter AllocAlignAttrEmitter(*
this, TargetDecl, CallArgs);
6328 Attrs = AllocAlignAttrEmitter.TryEmitAsCallSiteAttribute(Attrs);
6333 CI =
Builder.CreateCall(IRFuncTy, CalleePtr, IRCallArgs, BundleList);
6336 CI =
Builder.CreateInvoke(IRFuncTy, CalleePtr, Cont, InvokeDest, IRCallArgs,
6340 if (CI->getCalledFunction() && CI->getCalledFunction()->hasName() &&
6341 CI->getCalledFunction()->getName().starts_with(
"_Z4sqrt")) {
6346 if (
CGM.getCodeGenOpts().CallGraphSection) {
6350 else if (
const auto *FPT =
6351 Callee.getAbstractInfo().getCalleeFunctionProtoType())
6355 "Cannot find the callee type to generate callee_type metadata.");
6359 CGM.createCalleeTypeMetadataForIcall(CST, *callOrInvoke);
6366 if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(
CurFuncDecl)) {
6367 if (
const auto *A = FD->getAttr<CFGuardAttr>()) {
6368 if (A->getGuard() == CFGuardAttr::GuardArg::nocf &&
6369 !CI->getCalledFunction())
6375 CI->setAttributes(Attrs);
6376 CI->setCallingConv(
static_cast<llvm::CallingConv::ID
>(
CallingConv));
6380 if (!CI->getType()->isVoidTy())
6381 CI->setName(
"call");
6383 if (
CGM.shouldEmitConvergenceTokens() && CI->isConvergent())
6384 CI = addConvergenceControlToken(CI);
6387 LargestVectorWidth =
6393 if (!CI->getCalledFunction())
6394 PGO->valueProfile(
Builder, llvm::IPVK_IndirectCallTarget, CI, CalleePtr);
6398 if (
CGM.getLangOpts().ObjCAutoRefCount)
6399 AddObjCARCExceptionMetadata(CI);
6402 bool IsPPC =
getTarget().getTriple().isPPC();
6403 bool IsMIPS =
getTarget().getTriple().isMIPS();
6404 bool HasMips16 =
false;
6407 HasMips16 = TargetOpts.
FeatureMap.lookup(
"mips16");
6409 HasMips16 = llvm::is_contained(TargetOpts.
Features,
"+mips16");
6411 if (llvm::CallInst *
Call = dyn_cast<llvm::CallInst>(CI)) {
6412 if (TargetDecl && TargetDecl->
hasAttr<NotTailCalledAttr>())
6413 Call->setTailCallKind(llvm::CallInst::TCK_NoTail);
6414 else if (IsMustTail) {
6417 CGM.getDiags().Report(Loc, diag::err_aix_musttail_unsupported);
6420 CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail) << 0;
6421 else if (
Call->isIndirectCall())
6422 CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail) << 1;
6423 else if (isa_and_nonnull<FunctionDecl>(TargetDecl)) {
6428 CGM.addUndefinedGlobalForTailCall(
6431 llvm::GlobalValue::LinkageTypes
Linkage =
CGM.getFunctionLinkage(
6433 if (llvm::GlobalValue::isWeakForLinker(
Linkage) ||
6434 llvm::GlobalValue::isDiscardableIfUnused(
Linkage))
6435 CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail)
6443 CGM.getDiags().Report(Loc, diag::err_mips_impossible_musttail) << 0;
6444 else if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
6445 CGM.addUndefinedGlobalForTailCall({FD, Loc});
6447 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
6461 bool NeedSrcLoc = TargetDecl->
hasAttr<ErrorAttr>();
6462 if (!NeedSrcLoc &&
CGM.getCodeGenOpts().ShowInliningChain) {
6463 if (
const auto *FD = dyn_cast<FunctionDecl>(TargetDecl))
6464 NeedSrcLoc = FD->isInlined() || FD->hasAttr<AlwaysInlineAttr>() ||
6466 FD->isInAnonymousNamespace();
6470 auto *MD = llvm::ConstantAsMetadata::get(
Line);
6471 CI->setMetadata(
"srcloc", llvm::MDNode::get(
getLLVMContext(), {MD}));
6480 if (CI->doesNotReturn()) {
6481 if (NeedSRetLifetimeEnd)
6485 if (
SanOpts.has(SanitizerKind::Unreachable)) {
6488 if (
auto *F = CI->getCalledFunction())
6489 F->removeFnAttr(llvm::Attribute::NoReturn);
6490 CI->removeFnAttr(llvm::Attribute::NoReturn);
6494 if (
SanOpts.hasOneOf(SanitizerKind::Address |
6495 SanitizerKind::KernelAddress)) {
6497 llvm::IRBuilder<>::InsertPointGuard IPGuard(
Builder);
6499 auto *FnType = llvm::FunctionType::get(
CGM.VoidTy,
false);
6500 llvm::FunctionCallee Fn =
6501 CGM.CreateRuntimeFunction(FnType,
"__asan_handle_no_return");
6507 Builder.ClearInsertionPoint();
6529 if (CI->doesNotThrow())
6532 diag::err_musttail_noexcept_mismatch);
6538 if (Cleanup && Cleanup->isFakeUse()) {
6539 CGBuilderTy::InsertPointGuard IPG(
Builder);
6541 Cleanup->getCleanup()->Emit(*
this, EHScopeStack::Cleanup::Flags());
6542 }
else if (!(Cleanup &&
6543 Cleanup->getCleanup()->isRedundantBeforeReturn())) {
6544 CGM.ErrorUnsupported(
MustTailCall,
"tail call skipping over cleanups");
6547 if (CI->getType()->isVoidTy())
6551 Builder.ClearInsertionPoint();
6557 if (swiftErrorTemp.
isValid()) {
6558 llvm::Value *errorResult =
Builder.CreateLoad(swiftErrorTemp);
6559 Builder.CreateStore(errorResult, swiftErrorArg);
6576 if (IsVirtualFunctionPointerThunk) {
6589 unsigned unpaddedIndex = 0;
6590 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
6591 llvm::Type *eltType = coercionType->getElementType(i);
6595 llvm::Value *elt = CI;
6596 if (requiresExtract)
6597 elt =
Builder.CreateExtractValue(elt, unpaddedIndex++);
6599 assert(unpaddedIndex == 0);
6600 Builder.CreateStore(elt, eltAddr);
6608 if (NeedSRetLifetimeEnd)
6625 llvm::Value *Real =
Builder.CreateExtractValue(CI, 0);
6626 llvm::Value *Imag =
Builder.CreateExtractValue(CI, 1);
6634 llvm::Value *
V = CI;
6635 if (
V->getType() != RetIRTy)
6645 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(RetIRTy)) {
6646 llvm::Value *
V = CI;
6647 if (
auto *ScalableSrcTy =
6648 dyn_cast<llvm::ScalableVectorType>(
V->getType())) {
6649 if (FixedDstTy->getElementType() ==
6650 ScalableSrcTy->getElementType()) {
6651 V =
Builder.CreateExtractVector(FixedDstTy,
V, uint64_t(0),
6661 getContext().getTypeInfoDataSizeInChars(RetTy).Width.getQuantity();
6665 DestIsVolatile =
false;
6666 DestSize =
getContext().getTypeSizeInChars(RetTy).getQuantity();
6676 CI, RetTy, StorePtr,
6690 DestIsVolatile =
false;
6692 CGM.getABIInfo().createCoercedStore(CI, StorePtr, RetAI, DestIsVolatile,
6699 llvm_unreachable(
"Invalid ABI kind for return argument");
6702 llvm_unreachable(
"Unhandled ABIArgInfo::Kind");
6707 if (Ret.isScalar() && TargetDecl) {
6708 AssumeAlignedAttrEmitter.EmitAsAnAssumption(Loc, RetTy, Ret);
6709 AllocAlignAttrEmitter.EmitAsAnAssumption(Loc, RetTy, Ret);
6727 if (CalleeDecl && !CalleeDecl->
hasAttr<NoDebugAttr>() &&
6728 DI->getCallSiteRelatedAttrs() != llvm::DINode::FlagZero) {
6729 CodeGenFunction CalleeCGF(
CGM);
6731 Callee.getAbstractInfo().getCalleeDecl();
6732 CalleeCGF.
CurGD = CalleeGlobalDecl;
6735 DI->EmitFuncDeclForCallSite(
6736 CI, DI->getFunctionType(CalleeDecl, ResTy, Args), CalleeGlobalDecl);
6739 DI->addCallTargetIfVirtual(CalleeDecl, CI);
6760 VAListAddr =
VE->isMicrosoftABI()
6767 if (
VE->isMicrosoftABI())
6768 return CGM.getABIInfo().EmitMSVAArg(*
this, VAListAddr, Ty, Slot);
6770 return CGM.getABIInfo().EmitZOSVAArg(*
this, VAListAddr, Ty, Slot);
6771 return CGM.getABIInfo().EmitVAArg(*
this, VAListAddr, Ty, Slot);
6776 CGF.disableDebugInfo();
6780 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 CanQual< FunctionProtoType > GetFormalType(const CXXMethodDecl *MD)
Returns the canonical formal type of the given C++ method.
static bool DetermineNoUndef(QualType QTy, CodeGenTypes &Types, const llvm::DataLayout &DL, const ABIArgInfo &AI, bool CheckCoerce=true)
static const Expr * maybeGetUnaryAddrOfOperand(const Expr *E)
static void deactivateArgCleanupsBeforeCall(CodeGenFunction &CGF, const CallArgList &CallArgs)
static bool isProvablyNonNull(Address Addr, CodeGenFunction &CGF)
static llvm::Value * emitArgumentDemotion(CodeGenFunction &CGF, const VarDecl *var, llvm::Value *value)
An argument came in as a promoted argument; demote it back to its declared type.
SmallVector< CanQualType, 16 > CanQualTypeList
static std::pair< llvm::Value *, bool > CoerceScalableToFixed(CodeGenFunction &CGF, llvm::FixedVectorType *ToTy, llvm::ScalableVectorType *FromTy, llvm::Value *V, StringRef Name="")
static const CGFunctionInfo & arrangeLLVMFunctionInfo(CodeGenTypes &CGT, bool instanceMethod, SmallVectorImpl< CanQualType > &prefix, CanQual< FunctionProtoType > FTP)
Arrange the LLVM function layout for a value of the given function type, on top of any implicit param...
static 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 void setCUDAKernelCallingConvention(CanQualType &FTy, CodeGenModule &CGM, const FunctionDecl *FD)
Set calling convention for CUDA/HIP kernel.
static llvm::Value * tryEmitFusedAutoreleaseOfResult(CodeGenFunction &CGF, llvm::Value *result)
Try to emit a fused autorelease of a return result.
static Address EnterStructPointerForCoercedAccess(Address SrcPtr, llvm::StructType *SrcSTy, uint64_t DstSize, CodeGenFunction &CGF)
EnterStructPointerForCoercedAccess - Given a struct pointer that we are accessing some number of byte...
static llvm::Value * emitAutoreleaseOfResult(CodeGenFunction &CGF, llvm::Value *result)
Emit an ARC autorelease of the result of a function.
static void emitWriteback(CodeGenFunction &CGF, const CallArgList::Writeback &writeback)
Emit the actual writing-back of a writeback.
static bool HasStrictReturn(const CodeGenModule &Module, QualType RetTy, const Decl *TargetDecl)
static CanQualTypeList getArgTypesForDeclaration(ASTContext &ctx, const FunctionArgList &args)
static void addMergableDefaultFunctionAttributes(const CodeGenOptions &CodeGenOpts, llvm::AttrBuilder &FuncAttrs)
Add default attributes to a function, which have merge semantics under -mlink-builtin-bitcode and sho...
static 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 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 unsigned getNoFPClassTestMask(const LangOptions &langOpts)
Compute the nofpclass mask for FP types based on language options.
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.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
llvm::DenormalMode FPDenormalMode
The floating-point denormal mode to use.
static StringRef getFramePointerKindName(FramePointerKind Kind)
std::vector< std::string > Reciprocals
llvm::DenormalMode FP32DenormalMode
The floating-point denormal mode to use, for float.
std::string TrapFuncName
If not an empty string, trap intrinsics are lowered to calls to this function instead of to trap inst...
std::vector< std::string > DefaultFunctionAttrs
std::string PreferVectorWidth
The preferred width for auto-vectorization transforms.
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
unsigned getInAllocaFieldIndex() const
bool getIndirectByVal() const
llvm::StructType * getCoerceAndExpandType() const
bool getIndirectRealign() const
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 getIndirect(CharUnits Alignment, unsigned AddrSpace, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
ArrayRef< llvm::Type * > getCoerceAndExpandTypeSequence() const
bool isCoerceAndExpand() const
static ABIArgInfo getZeroExtend(QualType Ty, llvm::Type *T=nullptr)
static ABIArgInfo getExtend(QualType Ty, llvm::Type *T=nullptr)
unsigned getInAllocaIndirect() const
llvm::Type * getCoerceToType() const
bool isIndirectAliased() const
bool isSRetAfterThis() const
bool canHaveCoerceToType() const
static ABIArgInfo getSignExtend(QualType Ty, llvm::Type *T=nullptr)
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.
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.
@ ForceLeftToRight
! Language semantics require left-to-right evaluation.
@ ForceRightToLeft
! Language semantics require right-to-left evaluation.
void EmitNonNullArgCheck(RValue RV, QualType ArgType, SourceLocation ArgLoc, AbstractCallee AC, unsigned ParmNum)
Create a check for a function parameter that may potentially be declared as non-null.
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
const TargetInfo & getTarget() const
LValue EmitHLSLOutArgExpr(const HLSLOutArgExpr *E, CallArgList &Args, QualType Ty)
void EmitWritebacks(const CallArgList &Args)
EmitWriteback - Emit callbacks for function.
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
DeactivateCleanupBlock - Deactivates the given cleanup block.
void pushFullExprCleanup(CleanupKind kind, As... A)
pushFullExprCleanup - Push a cleanup to be run at the end of the current full-expression.
llvm::BasicBlock * getInvokeDest()
void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType)
EmitCallArg - Emit a single call argument.
void EmitPointerAuthOperandBundle(const CGPointerAuthInfo &Info, SmallVectorImpl< llvm::OperandBundleDef > &Bundles)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
AggValueSlot CreateAggTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateAggTemp - Create a temporary memory object for the given aggregate type.
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...
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 cleanup scope which generates the cleanup blocks lazily.
A saved depth on the scope stack.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
static LValue MakeAddr(Address Addr, QualType type, ASTContext &Context, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo)
Address getAddress() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
static RValue getAggregate(Address addr, bool isVolatile=false)
Convert an Address to an RValue.
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
An abstract representation of an aligned address.
CharUnits getAlignment() const
Return the alignment of this pointer.
llvm::Value * getPointer() const
static RawAddress invalid()
A class for recording the number of arguments that a function signature requires.
bool allowsOptionalArgs() const
unsigned getNumRequiredArgs() const
static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, unsigned additional)
Compute the arguments required by the given formal prototype, given that there may be some additional...
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
virtual void setCUDAKernelCallingConvention(const FunctionType *&FT) const
static void initPointerAuthFnAttributes(const PointerAuthOptions &Opts, llvm::AttrBuilder &FuncAttrs)
static void initBranchProtectionFnAttributes(const TargetInfo::BranchProtectionInfo &BPI, llvm::AttrBuilder &FuncAttrs)
virtual bool isNoProtoCallVariadic(const CodeGen::CallArgList &args, const FunctionNoProtoType *fnType) const
Determine whether a call to an unprototyped functions under the given calling convention should use t...
Complex values, per C99 6.2.5p11.
Represents the canonical version of C arrays with a specified constant size.
bool constructsVirtualBase() const
Returns true if the constructed base class is a virtual base class subobject of this declaration's cl...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Decl - This represents one declaration (or definition), e.g.
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
This represents one expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
bool isZeroLengthBitField() const
Is this a zero-length bit-field?
Represents a function declaration or definition.
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Represents a prototype with parameter type info, e.g.
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
unsigned getNumParams() const
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
ArrayRef< ExtParameterInfo > getExtParameterInfos() const
bool hasExtParameterInfos() const
Is there any interesting extra information for any of the parameters of this function type?
Wrapper for source info for functions.
A class which abstracts out some details necessary for making a call.
ExtInfo withCallingConv(CallingConv cc) const
CallingConv getCC() const
ExtInfo withProducesResult(bool producesResult) const
bool getCmseNSCall() const
bool getNoCfCheck() const
unsigned getRegParm() const
bool getNoCallerSavedRegs() const
bool getHasRegParm() const
bool getProducesResult() const
Interesting information about a specific parameter that can't simply be reflected in parameter's type...
ParameterABI getABI() const
Return the ABI treatment of this parameter.
ExtParameterInfo withIsNoEscape(bool NoEscape) const
FunctionType - C99 6.7.5.3 - Function Declarators.
ExtInfo getExtInfo() const
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
@ SME_AgnosticZAStateMask
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
QualType getReturnType() const
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
KernelReferenceKind getKernelReferenceKind() const
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 point when the lifetime of an automatic object ends.
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 isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isObjectType() const
Determine whether this type is an object type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isObjCRetainableType() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represents a call to the builtin function __builtin_va_arg.
Represents a variable declaration or definition.
QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const
Would the destruction of this variable have any effect, and if so, what kind?
Represents a GCC generic vector type.
Defines the clang::TargetInfo interface.
void computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI)
Compute the ABI information of a swiftcall function.
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
void computeSPIRKernelABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI)
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
void mergeDefaultFunctionDefinitionAttributes(llvm::Function &F, const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts, const TargetOptions &TargetOpts, bool WillInternalize)
Adds attributes to F according to our CodeGenOpts and LangOpts, as though we had emitted it ourselves...
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.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
CXXCtorType
C++ constructor types.
@ Ctor_DefaultClosure
Default closure variant of a ctor.
@ Ctor_CopyingClosure
Copying closure variant of a ctor.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
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)
Structure with information about how a bitfield should be accessed.
CharUnits StorageOffset
The offset of the bitfield storage from the start of the struct.
unsigned Offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the L...
unsigned Size
The total size of the bit-field, in bits.
unsigned StorageSize
The storage size in bits which should be used when accessing this bitfield.
Similar to AddedStructorArgs, but only notes the number of additional arguments.
llvm::Value * ToUse
A value to "use" after the writeback, or null.
LValue Source
The original argument.
Address Temporary
The temporary alloca.
const Expr * WritebackExpr
An Expression (optional) that performs the writeback with any required casting.
LValue getKnownLValue() const
RValue getKnownRValue() const
void copyInto(CodeGenFunction &CGF, Address A) const
RValue getRValue(CodeGenFunction &CGF) const
llvm::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)
static const EHPersonality & get(CodeGenModule &CGM, const FunctionDecl *FD)
llvm::Function * objc_retainAutoreleasedReturnValue
id objc_retainAutoreleasedReturnValue(id);
llvm::Function * objc_retain
id objc_retain(id);
llvm::InlineAsm * retainAutoreleasedReturnValueMarker
A void(void) inline asm to use to mark that the return value of a call will be immediately retain.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.