32#include "llvm/ADT/StringExtras.h"
33#include "llvm/Analysis/ValueTracking.h"
34#include "llvm/IR/Assumptions.h"
35#include "llvm/IR/AttributeMask.h"
36#include "llvm/IR/Attributes.h"
37#include "llvm/IR/CallingConv.h"
38#include "llvm/IR/DataLayout.h"
39#include "llvm/IR/InlineAsm.h"
40#include "llvm/IR/IntrinsicInst.h"
41#include "llvm/IR/Intrinsics.h"
42#include "llvm/IR/Type.h"
43#include "llvm/Transforms/Utils/Local.h"
46using namespace CodeGen;
52 default:
return llvm::CallingConv::C;
57 case CC_Win64:
return llvm::CallingConv::Win64;
59 case CC_AAPCS:
return llvm::CallingConv::ARM_AAPCS;
60 case CC_AAPCS_VFP:
return llvm::CallingConv::ARM_AAPCS_VFP;
73 case CC_Swift:
return llvm::CallingConv::Swift;
75 case CC_M68kRTD:
return llvm::CallingConv::M68k_RTD;
129 unsigned totalArgs) {
131 assert(paramInfos.size() <= prefixArgs);
132 assert(proto->
getNumParams() + prefixArgs <= totalArgs);
134 paramInfos.reserve(totalArgs);
137 paramInfos.resize(prefixArgs);
141 paramInfos.push_back(ParamInfo);
143 if (ParamInfo.hasPassObjectSize())
144 paramInfos.emplace_back();
147 assert(paramInfos.size() <= totalArgs &&
148 "Did we forget to insert pass_object_size args?");
150 paramInfos.resize(totalArgs);
160 if (!FPT->hasExtParameterInfos()) {
161 assert(paramInfos.empty() &&
162 "We have paramInfos, but the prototype doesn't?");
163 prefix.append(FPT->param_type_begin(), FPT->param_type_end());
167 unsigned PrefixSize = prefix.size();
171 prefix.reserve(prefix.size() + FPT->getNumParams());
173 auto ExtInfos = FPT->getExtParameterInfos();
174 assert(ExtInfos.size() == FPT->getNumParams());
175 for (
unsigned I = 0, E = FPT->getNumParams(); I != E; ++I) {
176 prefix.push_back(FPT->getParamType(I));
177 if (ExtInfos[I].hasPassObjectSize())
200 FTP->getExtInfo(), paramInfos,
Required);
208 return ::arrangeLLVMFunctionInfo(*
this,
false, argTypes,
218 if (D->
hasAttr<FastCallAttr>())
224 if (D->
hasAttr<ThisCallAttr>())
227 if (D->
hasAttr<VectorCallAttr>())
233 if (PcsAttr *PCS = D->
getAttr<PcsAttr>())
236 if (D->
hasAttr<AArch64VectorPcsAttr>())
239 if (D->
hasAttr<AArch64SVEPcsAttr>())
242 if (D->
hasAttr<AMDGPUKernelCallAttr>())
245 if (D->
hasAttr<IntelOclBiccAttr>())
254 if (D->
hasAttr<PreserveMostAttr>())
257 if (D->
hasAttr<PreserveAllAttr>())
263 if (D->
hasAttr<PreserveNoneAttr>())
266 if (D->
hasAttr<RISCVVectorCCAttr>())
287 return ::arrangeLLVMFunctionInfo(
288 *
this,
true, argTypes,
295 if (FD->
hasAttr<CUDAGlobalAttr>()) {
308 assert(!isa<CXXConstructorDecl>(MD) &&
"wrong method for constructors!");
309 assert(!isa<CXXDestructorDecl>(MD) &&
"wrong method for destructors!");
330 !
Target.getCXXABI().hasConstructorVariants();
335 auto *MD = cast<CXXMethodDecl>(GD.
getDecl());
343 bool PassParams =
true;
345 if (
auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
348 if (
auto Inherited = CD->getInheritedConstructor())
360 if (!paramInfos.empty()) {
363 paramInfos.insert(paramInfos.begin() + 1, AddedArgs.
Prefix,
366 paramInfos.append(AddedArgs.
Suffix,
371 (PassParams && MD->isVariadic() ?
RequiredArgs(argTypes.size())
381 argTypes, extInfo, paramInfos, required);
387 for (
auto &arg : args)
395 for (
auto &arg : args)
402 unsigned prefixArgs,
unsigned totalArgs) {
422 unsigned ExtraPrefixArgs,
423 unsigned ExtraSuffixArgs,
424 bool PassProtoArgs) {
427 for (
const auto &Arg : args)
431 unsigned TotalPrefixArgs = 1 + ExtraPrefixArgs;
436 FPT, TotalPrefixArgs + ExtraSuffixArgs)
450 if (PassProtoArgs && FPT->hasExtParameterInfos()) {
457 ArgTypes, Info, ParamInfos,
Required);
465 if (MD->isImplicitObjectMemberFunction())
470 assert(isa<FunctionType>(FTy));
477 std::nullopt, noProto->getExtInfo(), {},
512 I->hasAttr<NoEscapeAttr>());
513 extParamInfos.push_back(extParamInfo);
520 if (
getContext().getLangOpts().ObjCAutoRefCount &&
521 MD->
hasAttr<NSReturnsRetainedAttr>())
547 if (isa<CXXConstructorDecl>(GD.
getDecl()) ||
548 isa<CXXDestructorDecl>(GD.
getDecl()))
561 assert(MD->
isVirtual() &&
"only methods have thunks");
578 ArgTys.push_back(*FTP->param_type_begin());
580 ArgTys.push_back(Context.
IntTy);
595 unsigned numExtraRequiredArgs,
597 assert(args.size() >= numExtraRequiredArgs);
607 if (proto->isVariadic())
610 if (proto->hasExtParameterInfos())
620 cast<FunctionNoProtoType>(fnType))) {
626 for (
const auto &arg : args)
631 paramInfos, required);
643 chainCall ? 1 : 0, chainCall);
672 for (
const auto &Arg : args)
705 unsigned numPrefixArgs) {
706 assert(numPrefixArgs + 1 <= args.size() &&
707 "Emitting a call with less args than the required prefix?");
719 paramInfos, required);
731 assert(signature.
arg_size() <= args.size());
732 if (signature.
arg_size() == args.size())
737 if (!sigParamInfos.empty()) {
738 paramInfos.append(sigParamInfos.begin(), sigParamInfos.end());
739 paramInfos.resize(args.size());
771 assert(llvm::all_of(argTypes,
775 llvm::FoldingSetNodeID ID;
780 bool isDelegateCall =
783 info, paramInfos, required, resultType, argTypes);
785 void *insertPos =
nullptr;
786 CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, insertPos);
794 info, paramInfos, resultType, argTypes, required);
795 FunctionInfos.InsertNode(FI, insertPos);
797 bool inserted = FunctionsBeingProcessed.insert(FI).second;
799 assert(inserted &&
"Recursively being processed?");
802 if (CC == llvm::CallingConv::SPIR_KERNEL) {
820 if (I.info.canHaveCoerceToType() && I.info.getCoerceToType() ==
nullptr)
823 bool erased = FunctionsBeingProcessed.erase(FI); (void)erased;
824 assert(erased &&
"Not in set?");
830 bool chainCall,
bool delegateCall,
836 assert(paramInfos.empty() || paramInfos.size() == argTypes.size());
841 operator new(totalSizeToAlloc<ArgInfo, ExtParameterInfo>(
842 argTypes.size() + 1, paramInfos.size()));
845 FI->CallingConvention = llvmCC;
846 FI->EffectiveCallingConvention = llvmCC;
847 FI->ASTCallingConvention = info.
getCC();
848 FI->InstanceMethod = instanceMethod;
849 FI->ChainCall = chainCall;
850 FI->DelegateCall = delegateCall;
856 FI->Required = required;
859 FI->ArgStruct =
nullptr;
860 FI->ArgStructAlign = 0;
861 FI->NumArgs = argTypes.size();
862 FI->HasExtParameterInfos = !paramInfos.empty();
863 FI->getArgsBuffer()[0].
type = resultType;
864 FI->MaxVectorWidth = 0;
865 for (
unsigned i = 0, e = argTypes.size(); i != e; ++i)
866 FI->getArgsBuffer()[i + 1].
type = argTypes[i];
867 for (
unsigned i = 0, e = paramInfos.size(); i != e; ++i)
868 FI->getExtParameterInfosBuffer()[i] = paramInfos[i];
878struct TypeExpansion {
879 enum TypeExpansionKind {
891 const TypeExpansionKind Kind;
893 TypeExpansion(TypeExpansionKind K) : Kind(K) {}
894 virtual ~TypeExpansion() {}
897struct ConstantArrayExpansion : TypeExpansion {
901 ConstantArrayExpansion(
QualType EltTy, uint64_t NumElts)
902 : TypeExpansion(TEK_ConstantArray), EltTy(EltTy), NumElts(NumElts) {}
903 static bool classof(
const TypeExpansion *TE) {
904 return TE->Kind == TEK_ConstantArray;
908struct RecordExpansion : TypeExpansion {
915 : TypeExpansion(TEK_Record), Bases(
std::move(Bases)),
916 Fields(
std::move(Fields)) {}
917 static bool classof(
const TypeExpansion *TE) {
918 return TE->Kind == TEK_Record;
922struct ComplexExpansion : TypeExpansion {
926 static bool classof(
const TypeExpansion *TE) {
931struct NoExpansion : TypeExpansion {
932 NoExpansion() : TypeExpansion(TEK_None) {}
933 static bool classof(
const TypeExpansion *TE) {
934 return TE->Kind == TEK_None;
939static std::unique_ptr<TypeExpansion>
942 return std::make_unique<ConstantArrayExpansion>(AT->getElementType(),
950 "Cannot expand structure with flexible array.");
957 for (
const auto *FD : RD->
fields()) {
958 if (FD->isZeroLengthBitField(Context))
960 assert(!FD->isBitField() &&
961 "Cannot expand structure with bit-field members.");
963 if (UnionSize < FieldSize) {
964 UnionSize = FieldSize;
969 Fields.push_back(LargestFD);
971 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
972 assert(!CXXRD->isDynamicClass() &&
973 "cannot expand vtable pointers in dynamic classes");
974 llvm::append_range(Bases, llvm::make_pointer_range(CXXRD->bases()));
977 for (
const auto *FD : RD->
fields()) {
978 if (FD->isZeroLengthBitField(Context))
980 assert(!FD->isBitField() &&
981 "Cannot expand structure with bit-field members.");
982 Fields.push_back(FD);
985 return std::make_unique<RecordExpansion>(std::move(Bases),
989 return std::make_unique<ComplexExpansion>(CT->getElementType());
991 return std::make_unique<NoExpansion>();
996 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
999 if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1001 for (
auto BS : RExp->Bases)
1003 for (
auto FD : RExp->Fields)
1007 if (isa<ComplexExpansion>(Exp.get()))
1009 assert(isa<NoExpansion>(Exp.get()));
1017 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1018 for (
int i = 0, n = CAExp->NumElts; i < n; i++) {
1021 }
else if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1022 for (
auto BS : RExp->Bases)
1024 for (
auto FD : RExp->Fields)
1026 }
else if (
auto CExp = dyn_cast<ComplexExpansion>(Exp.get())) {
1031 assert(isa<NoExpansion>(Exp.get()));
1037 ConstantArrayExpansion *CAE,
1039 llvm::function_ref<
void(
Address)> Fn) {
1040 for (
int i = 0, n = CAE->NumElts; i < n; i++) {
1047 llvm::Function::arg_iterator &AI) {
1049 "Unexpected non-simple lvalue during struct expansion.");
1052 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1055 LValue LV = MakeAddrLValue(EltAddr, CAExp->EltTy);
1056 ExpandTypeFromArgs(CAExp->EltTy, LV, AI);
1058 }
else if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1068 ExpandTypeFromArgs(BS->
getType(), SubLV, AI);
1070 for (
auto FD : RExp->Fields) {
1073 ExpandTypeFromArgs(FD->getType(), SubLV, AI);
1075 }
else if (isa<ComplexExpansion>(Exp.get())) {
1076 auto realValue = &*AI++;
1077 auto imagValue = &*AI++;
1082 assert(isa<NoExpansion>(Exp.get()));
1083 llvm::Value *Arg = &*AI++;
1090 if (Arg->getType()->isPointerTy()) {
1099void CodeGenFunction::ExpandTypeToArgs(
1103 if (
auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1107 *
this, CAExp, Addr, [&](
Address EltAddr) {
1111 ExpandTypeToArgs(CAExp->EltTy, EltArg, IRFuncTy, IRCallArgs,
1114 }
else if (
auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1125 ExpandTypeToArgs(BS->
getType(), BaseArg, IRFuncTy, IRCallArgs,
1130 for (
auto FD : RExp->Fields) {
1133 ExpandTypeToArgs(FD->getType(), FldArg, IRFuncTy, IRCallArgs,
1136 }
else if (isa<ComplexExpansion>(Exp.get())) {
1138 IRCallArgs[IRCallArgPos++] = CV.first;
1139 IRCallArgs[IRCallArgPos++] = CV.second;
1141 assert(isa<NoExpansion>(Exp.get()));
1143 assert(RV.isScalar() &&
1144 "Unexpected non-scalar rvalue during struct expansion.");
1147 llvm::Value *
V = RV.getScalarVal();
1148 if (IRCallArgPos < IRFuncTy->getNumParams() &&
1149 V->getType() != IRFuncTy->getParamType(IRCallArgPos))
1150 V =
Builder.CreateBitCast(
V, IRFuncTy->getParamType(IRCallArgPos));
1152 IRCallArgs[IRCallArgPos++] =
V;
1160 const Twine &Name =
"tmp") {
1174 llvm::StructType *SrcSTy,
1177 if (SrcSTy->getNumElements() == 0)
return SrcPtr;
1185 uint64_t FirstEltSize =
1187 if (FirstEltSize < DstSize &&
1196 if (llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy))
1212 if (Val->getType() == Ty)
1215 if (isa<llvm::PointerType>(Val->getType())) {
1217 if (isa<llvm::PointerType>(Ty))
1218 return CGF.
Builder.CreateBitCast(Val, Ty,
"coerce.val");
1224 llvm::Type *DestIntTy = Ty;
1225 if (isa<llvm::PointerType>(DestIntTy))
1228 if (Val->getType() != DestIntTy) {
1230 if (DL.isBigEndian()) {
1233 uint64_t SrcSize = DL.getTypeSizeInBits(Val->getType());
1234 uint64_t DstSize = DL.getTypeSizeInBits(DestIntTy);
1236 if (SrcSize > DstSize) {
1237 Val = CGF.
Builder.CreateLShr(Val, SrcSize - DstSize,
"coerce.highbits");
1238 Val = CGF.
Builder.CreateTrunc(Val, DestIntTy,
"coerce.val.ii");
1240 Val = CGF.
Builder.CreateZExt(Val, DestIntTy,
"coerce.val.ii");
1241 Val = CGF.
Builder.CreateShl(Val, DstSize - SrcSize,
"coerce.highbits");
1245 Val = CGF.
Builder.CreateIntCast(Val, DestIntTy,
false,
"coerce.val.ii");
1249 if (isa<llvm::PointerType>(Ty))
1250 Val = CGF.
Builder.CreateIntToPtr(Val, Ty,
"coerce.val.ip");
1273 if (llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy)) {
1275 DstSize.getFixedValue(), CGF);
1283 if ((isa<llvm::IntegerType>(Ty) || isa<llvm::PointerType>(Ty)) &&
1284 (isa<llvm::IntegerType>(SrcTy) || isa<llvm::PointerType>(SrcTy))) {
1290 if (!SrcSize.isScalable() && !DstSize.isScalable() &&
1291 SrcSize.getFixedValue() >= DstSize.getFixedValue()) {
1305 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(Ty)) {
1306 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
1309 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
1310 ScalableDstTy->getElementCount().isKnownMultipleOf(8) &&
1311 FixedSrcTy->getElementType()->isIntegerTy(8)) {
1312 ScalableDstTy = llvm::ScalableVectorType::get(
1313 FixedSrcTy->getElementType(),
1314 ScalableDstTy->getElementCount().getKnownMinValue() / 8);
1316 if (ScalableDstTy->getElementType() == FixedSrcTy->getElementType()) {
1318 auto *UndefVec = llvm::UndefValue::get(ScalableDstTy);
1319 auto *Zero = llvm::Constant::getNullValue(CGF.
CGM.
Int64Ty);
1321 ScalableDstTy, UndefVec, Load, Zero,
"cast.scalable");
1322 if (ScalableDstTy != Ty)
1335 llvm::ConstantInt::get(CGF.
IntPtrTy, SrcSize.getKnownMinValue()));
1344 bool DestIsVolatile) {
1346 if (llvm::StructType *STy = dyn_cast<llvm::StructType>(Val->getType())) {
1347 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1349 llvm::Value *Elt =
Builder.CreateExtractValue(Val, i);
1367 llvm::Type *SrcTy = Src->getType();
1369 if (SrcTy == DstTy) {
1376 if (llvm::StructType *DstSTy = dyn_cast<llvm::StructType>(DstTy)) {
1378 SrcSize.getFixedValue(), CGF);
1382 llvm::PointerType *SrcPtrTy = llvm::dyn_cast<llvm::PointerType>(SrcTy);
1383 llvm::PointerType *DstPtrTy = llvm::dyn_cast<llvm::PointerType>(DstTy);
1384 if (SrcPtrTy && DstPtrTy &&
1385 SrcPtrTy->getAddressSpace() != DstPtrTy->getAddressSpace()) {
1393 if ((isa<llvm::IntegerType>(SrcTy) || isa<llvm::PointerType>(SrcTy)) &&
1394 (isa<llvm::IntegerType>(DstTy) || isa<llvm::PointerType>(DstTy))) {
1403 if (isa<llvm::ScalableVectorType>(SrcTy) ||
1404 isa<llvm::ScalableVectorType>(DstTy) ||
1405 SrcSize.getFixedValue() <= DstSize.getFixedValue()) {
1424 llvm::ConstantInt::get(CGF.
IntPtrTy, DstSize.getFixedValue()));
1443class ClangToLLVMArgMapping {
1444 static const unsigned InvalidIndex = ~0
U;
1445 unsigned InallocaArgNo;
1447 unsigned TotalIRArgs;
1451 unsigned PaddingArgIndex;
1454 unsigned FirstArgIndex;
1455 unsigned NumberOfArgs;
1458 : PaddingArgIndex(InvalidIndex), FirstArgIndex(InvalidIndex),
1466 bool OnlyRequiredArgs =
false)
1467 : InallocaArgNo(InvalidIndex), SRetArgNo(InvalidIndex), TotalIRArgs(0),
1468 ArgInfo(OnlyRequiredArgs ? FI.getNumRequiredArgs() : FI.arg_size()) {
1469 construct(Context, FI, OnlyRequiredArgs);
1472 bool hasInallocaArg()
const {
return InallocaArgNo != InvalidIndex; }
1473 unsigned getInallocaArgNo()
const {
1474 assert(hasInallocaArg());
1475 return InallocaArgNo;
1478 bool hasSRetArg()
const {
return SRetArgNo != InvalidIndex; }
1479 unsigned getSRetArgNo()
const {
1480 assert(hasSRetArg());
1484 unsigned totalIRArgs()
const {
return TotalIRArgs; }
1486 bool hasPaddingArg(
unsigned ArgNo)
const {
1487 assert(ArgNo < ArgInfo.size());
1488 return ArgInfo[ArgNo].PaddingArgIndex != InvalidIndex;
1490 unsigned getPaddingArgNo(
unsigned ArgNo)
const {
1491 assert(hasPaddingArg(ArgNo));
1492 return ArgInfo[ArgNo].PaddingArgIndex;
1497 std::pair<unsigned, unsigned> getIRArgs(
unsigned ArgNo)
const {
1498 assert(ArgNo < ArgInfo.size());
1499 return std::make_pair(ArgInfo[ArgNo].FirstArgIndex,
1500 ArgInfo[ArgNo].NumberOfArgs);
1505 bool OnlyRequiredArgs);
1508void ClangToLLVMArgMapping::construct(
const ASTContext &Context,
1510 bool OnlyRequiredArgs) {
1511 unsigned IRArgNo = 0;
1512 bool SwapThisWithSRet =
false;
1517 SRetArgNo = SwapThisWithSRet ? 1 : IRArgNo++;
1528 auto &IRArgs = ArgInfo[ArgNo];
1531 IRArgs.PaddingArgIndex = IRArgNo++;
1537 llvm::StructType *STy = dyn_cast<llvm::StructType>(AI.
getCoerceToType());
1539 IRArgs.NumberOfArgs = STy->getNumElements();
1541 IRArgs.NumberOfArgs = 1;
1547 IRArgs.NumberOfArgs = 1;
1552 IRArgs.NumberOfArgs = 0;
1562 if (IRArgs.NumberOfArgs > 0) {
1563 IRArgs.FirstArgIndex = IRArgNo;
1564 IRArgNo += IRArgs.NumberOfArgs;
1569 if (IRArgNo == 1 && SwapThisWithSRet)
1572 assert(ArgNo == ArgInfo.size());
1575 InallocaArgNo = IRArgNo++;
1577 TotalIRArgs = IRArgNo;
1585 return RI.
isIndirect() || (RI.isInAlloca() && RI.getInAllocaSRet());
1600 switch (BT->getKind()) {
1603 case BuiltinType::Float:
1605 case BuiltinType::Double:
1607 case BuiltinType::LongDouble:
1618 if (BT->getKind() == BuiltinType::LongDouble)
1634 bool Inserted = FunctionsBeingProcessed.insert(&FI).second;
1636 assert(Inserted &&
"Recursively being processed?");
1638 llvm::Type *resultType =
nullptr;
1643 llvm_unreachable(
"Invalid ABI kind for return argument");
1655 resultType = llvm::PointerType::get(
getLLVMContext(), addressSpace);
1671 ClangToLLVMArgMapping IRFunctionArgs(
getContext(), FI,
true);
1675 if (IRFunctionArgs.hasSRetArg()) {
1678 ArgTypes[IRFunctionArgs.getSRetArgNo()] =
1683 if (IRFunctionArgs.hasInallocaArg())
1684 ArgTypes[IRFunctionArgs.getInallocaArgNo()] =
1691 for (; it != ie; ++it, ++ArgNo) {
1695 if (IRFunctionArgs.hasPaddingArg(ArgNo))
1696 ArgTypes[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
1699 unsigned FirstIRArg, NumIRArgs;
1700 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
1705 assert(NumIRArgs == 0);
1709 assert(NumIRArgs == 1);
1711 ArgTypes[FirstIRArg] = llvm::PointerType::get(
1715 assert(NumIRArgs == 1);
1716 ArgTypes[FirstIRArg] = llvm::PointerType::get(
1724 llvm::StructType *st = dyn_cast<llvm::StructType>(argType);
1726 assert(NumIRArgs == st->getNumElements());
1727 for (
unsigned i = 0, e = st->getNumElements(); i != e; ++i)
1728 ArgTypes[FirstIRArg + i] = st->getElementType(i);
1730 assert(NumIRArgs == 1);
1731 ArgTypes[FirstIRArg] = argType;
1737 auto ArgTypesIter = ArgTypes.begin() + FirstIRArg;
1739 *ArgTypesIter++ = EltTy;
1741 assert(ArgTypesIter == ArgTypes.begin() + FirstIRArg + NumIRArgs);
1746 auto ArgTypesIter = ArgTypes.begin() + FirstIRArg;
1748 assert(ArgTypesIter == ArgTypes.begin() + FirstIRArg + NumIRArgs);
1753 bool Erased = FunctionsBeingProcessed.erase(&FI); (void)Erased;
1754 assert(Erased &&
"Not in set?");
1756 return llvm::FunctionType::get(resultType, ArgTypes, FI.
isVariadic());
1770 llvm::AttrBuilder &FuncAttrs,
1777 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
1781 FuncAttrs.addAttribute(
"aarch64_pstate_sm_enabled");
1783 FuncAttrs.addAttribute(
"aarch64_pstate_sm_compatible");
1787 FuncAttrs.addAttribute(
"aarch64_preserves_za");
1789 FuncAttrs.addAttribute(
"aarch64_in_za");
1791 FuncAttrs.addAttribute(
"aarch64_out_za");
1793 FuncAttrs.addAttribute(
"aarch64_inout_za");
1797 FuncAttrs.addAttribute(
"aarch64_preserves_zt0");
1799 FuncAttrs.addAttribute(
"aarch64_in_zt0");
1801 FuncAttrs.addAttribute(
"aarch64_out_zt0");
1803 FuncAttrs.addAttribute(
"aarch64_inout_zt0");
1807 const Decl *Callee) {
1813 for (
const OMPAssumeAttr *AA : Callee->specific_attrs<OMPAssumeAttr>())
1814 AA->getAssumption().split(Attrs,
",");
1817 FuncAttrs.addAttribute(llvm::AssumptionAttrKey,
1818 llvm::join(Attrs.begin(), Attrs.end(),
","));
1827 if (
const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl()))
1828 return ClassDecl->hasTrivialDestructor();
1834 const Decl *TargetDecl) {
1840 if (
Module.getLangOpts().Sanitize.has(SanitizerKind::Memory))
1844 if (!
Module.getLangOpts().CPlusPlus)
1847 if (
const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(TargetDecl)) {
1848 if (FDecl->isExternC())
1850 }
else if (
const VarDecl *VDecl = dyn_cast<VarDecl>(TargetDecl)) {
1852 if (VDecl->isExternC())
1860 return Module.getCodeGenOpts().StrictReturn ||
1861 !
Module.MayDropFunctionReturn(
Module.getContext(), RetTy) ||
1862 Module.getLangOpts().Sanitize.has(SanitizerKind::Return);
1869 llvm::DenormalMode FP32DenormalMode,
1870 llvm::AttrBuilder &FuncAttrs) {
1871 if (FPDenormalMode != llvm::DenormalMode::getDefault())
1872 FuncAttrs.addAttribute(
"denormal-fp-math", FPDenormalMode.str());
1874 if (FP32DenormalMode != FPDenormalMode && FP32DenormalMode.isValid())
1875 FuncAttrs.addAttribute(
"denormal-fp-math-f32", FP32DenormalMode.str());
1883 llvm::AttrBuilder &FuncAttrs) {
1889 StringRef Name,
bool HasOptnone,
const CodeGenOptions &CodeGenOpts,
1891 llvm::AttrBuilder &FuncAttrs) {
1894 if (CodeGenOpts.OptimizeSize)
1895 FuncAttrs.addAttribute(llvm::Attribute::OptimizeForSize);
1896 if (CodeGenOpts.OptimizeSize == 2)
1897 FuncAttrs.addAttribute(llvm::Attribute::MinSize);
1900 if (CodeGenOpts.DisableRedZone)
1901 FuncAttrs.addAttribute(llvm::Attribute::NoRedZone);
1902 if (CodeGenOpts.IndirectTlsSegRefs)
1903 FuncAttrs.addAttribute(
"indirect-tls-seg-refs");
1904 if (CodeGenOpts.NoImplicitFloat)
1905 FuncAttrs.addAttribute(llvm::Attribute::NoImplicitFloat);
1907 if (AttrOnCallSite) {
1912 FuncAttrs.addAttribute(llvm::Attribute::NoBuiltin);
1914 FuncAttrs.addAttribute(
"trap-func-name", CodeGenOpts.
TrapFuncName);
1916 switch (CodeGenOpts.getFramePointer()) {
1922 FuncAttrs.addAttribute(
"frame-pointer",
1924 CodeGenOpts.getFramePointer()));
1927 if (CodeGenOpts.LessPreciseFPMAD)
1928 FuncAttrs.addAttribute(
"less-precise-fpmad",
"true");
1930 if (CodeGenOpts.NullPointerIsValid)
1931 FuncAttrs.addAttribute(llvm::Attribute::NullPointerIsValid);
1934 FuncAttrs.addAttribute(
"no-trapping-math",
"true");
1938 if (LangOpts.NoHonorInfs)
1939 FuncAttrs.addAttribute(
"no-infs-fp-math",
"true");
1940 if (LangOpts.NoHonorNaNs)
1941 FuncAttrs.addAttribute(
"no-nans-fp-math",
"true");
1942 if (LangOpts.ApproxFunc)
1943 FuncAttrs.addAttribute(
"approx-func-fp-math",
"true");
1944 if (LangOpts.AllowFPReassoc && LangOpts.AllowRecip &&
1945 LangOpts.NoSignedZero && LangOpts.ApproxFunc &&
1946 (LangOpts.getDefaultFPContractMode() ==
1948 LangOpts.getDefaultFPContractMode() ==
1950 FuncAttrs.addAttribute(
"unsafe-fp-math",
"true");
1951 if (CodeGenOpts.SoftFloat)
1952 FuncAttrs.addAttribute(
"use-soft-float",
"true");
1953 FuncAttrs.addAttribute(
"stack-protector-buffer-size",
1954 llvm::utostr(CodeGenOpts.SSPBufferSize));
1955 if (LangOpts.NoSignedZero)
1956 FuncAttrs.addAttribute(
"no-signed-zeros-fp-math",
"true");
1959 const std::vector<std::string> &Recips = CodeGenOpts.
Reciprocals;
1960 if (!Recips.empty())
1961 FuncAttrs.addAttribute(
"reciprocal-estimates",
1962 llvm::join(Recips,
","));
1966 FuncAttrs.addAttribute(
"prefer-vector-width",
1969 if (CodeGenOpts.StackRealignment)
1970 FuncAttrs.addAttribute(
"stackrealign");
1971 if (CodeGenOpts.Backchain)
1972 FuncAttrs.addAttribute(
"backchain");
1973 if (CodeGenOpts.EnableSegmentedStacks)
1974 FuncAttrs.addAttribute(
"split-stack");
1976 if (CodeGenOpts.SpeculativeLoadHardening)
1977 FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
1980 switch (CodeGenOpts.getZeroCallUsedRegs()) {
1981 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Skip:
1982 FuncAttrs.removeAttribute(
"zero-call-used-regs");
1984 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPRArg:
1985 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used-gpr-arg");
1987 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPR:
1988 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used-gpr");
1990 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedArg:
1991 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used-arg");
1993 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Used:
1994 FuncAttrs.addAttribute(
"zero-call-used-regs",
"used");
1996 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPRArg:
1997 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all-gpr-arg");
1999 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPR:
2000 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all-gpr");
2002 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllArg:
2003 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all-arg");
2005 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::All:
2006 FuncAttrs.addAttribute(
"zero-call-used-regs",
"all");
2017 FuncAttrs.addAttribute(llvm::Attribute::Convergent);
2022 if ((LangOpts.CUDA && LangOpts.CUDAIsDevice) || LangOpts.OpenCL ||
2023 LangOpts.SYCLIsDevice) {
2024 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2028 StringRef Var,
Value;
2030 FuncAttrs.addAttribute(Var,
Value);
2041 const llvm::Function &F,
2043 auto FFeatures = F.getFnAttribute(
"target-features");
2045 llvm::StringSet<> MergedNames;
2047 MergedFeatures.reserve(TargetOpts.
Features.size());
2049 auto AddUnmergedFeatures = [&](
auto &&FeatureRange) {
2050 for (StringRef Feature : FeatureRange) {
2051 if (Feature.empty())
2053 assert(Feature[0] ==
'+' || Feature[0] ==
'-');
2054 StringRef Name = Feature.drop_front(1);
2055 bool Merged = !MergedNames.insert(Name).second;
2057 MergedFeatures.push_back(Feature);
2061 if (FFeatures.isValid())
2062 AddUnmergedFeatures(llvm::split(FFeatures.getValueAsString(),
','));
2063 AddUnmergedFeatures(TargetOpts.
Features);
2065 if (!MergedFeatures.empty()) {
2066 llvm::sort(MergedFeatures);
2067 FuncAttr.addAttribute(
"target-features", llvm::join(MergedFeatures,
","));
2074 bool WillInternalize) {
2076 llvm::AttrBuilder FuncAttrs(F.getContext());
2079 if (!TargetOpts.
CPU.empty())
2080 FuncAttrs.addAttribute(
"target-cpu", TargetOpts.
CPU);
2081 if (!TargetOpts.
TuneCPU.empty())
2082 FuncAttrs.addAttribute(
"tune-cpu", TargetOpts.
TuneCPU);
2085 CodeGenOpts, LangOpts,
2088 if (!WillInternalize && F.isInterposable()) {
2093 F.addFnAttrs(FuncAttrs);
2097 llvm::AttributeMask AttrsToRemove;
2099 llvm::DenormalMode DenormModeToMerge = F.getDenormalModeRaw();
2100 llvm::DenormalMode DenormModeToMergeF32 = F.getDenormalModeF32Raw();
2101 llvm::DenormalMode Merged =
2105 if (DenormModeToMergeF32.isValid()) {
2110 if (Merged == llvm::DenormalMode::getDefault()) {
2111 AttrsToRemove.addAttribute(
"denormal-fp-math");
2112 }
else if (Merged != DenormModeToMerge) {
2114 FuncAttrs.addAttribute(
"denormal-fp-math",
2118 if (MergedF32 == llvm::DenormalMode::getDefault()) {
2119 AttrsToRemove.addAttribute(
"denormal-fp-math-f32");
2120 }
else if (MergedF32 != DenormModeToMergeF32) {
2122 FuncAttrs.addAttribute(
"denormal-fp-math-f32",
2126 F.removeFnAttrs(AttrsToRemove);
2131 F.addFnAttrs(FuncAttrs);
2134void CodeGenModule::getTrivialDefaultFunctionAttributes(
2135 StringRef Name,
bool HasOptnone,
bool AttrOnCallSite,
2136 llvm::AttrBuilder &FuncAttrs) {
2137 ::getTrivialDefaultFunctionAttributes(Name, HasOptnone,
getCodeGenOpts(),
2142void CodeGenModule::getDefaultFunctionAttributes(StringRef Name,
2144 bool AttrOnCallSite,
2145 llvm::AttrBuilder &FuncAttrs) {
2146 getTrivialDefaultFunctionAttributes(Name, HasOptnone, AttrOnCallSite,
2150 if (!AttrOnCallSite)
2155 llvm::AttrBuilder &attrs) {
2156 getDefaultFunctionAttributes(
"",
false,
2158 GetCPUAndFeaturesAttributes(
GlobalDecl(), attrs);
2163 const NoBuiltinAttr *NBA =
nullptr) {
2164 auto AddNoBuiltinAttr = [&FuncAttrs](StringRef BuiltinName) {
2166 AttributeName +=
"no-builtin-";
2167 AttributeName += BuiltinName;
2168 FuncAttrs.addAttribute(AttributeName);
2172 if (LangOpts.NoBuiltin) {
2174 FuncAttrs.addAttribute(
"no-builtins");
2188 if (llvm::is_contained(NBA->builtinNames(),
"*")) {
2189 FuncAttrs.addAttribute(
"no-builtins");
2194 llvm::for_each(NBA->builtinNames(), AddNoBuiltinAttr);
2198 const llvm::DataLayout &DL,
const ABIArgInfo &AI,
2199 bool CheckCoerce =
true) {
2200 llvm::Type *Ty = Types.ConvertTypeForMem(QTy);
2206 if (!DL.typeSizeEqualsStoreSize(Ty))
2213 if (llvm::TypeSize::isKnownGT(DL.getTypeSizeInBits(CoerceTy),
2214 DL.getTypeSizeInBits(Ty)))
2238 if (
const MatrixType *Matrix = dyn_cast<MatrixType>(QTy))
2240 if (
const ArrayType *Array = dyn_cast<ArrayType>(QTy))
2249 unsigned NumRequiredArgs,
unsigned ArgNo) {
2250 const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl);
2255 if (ArgNo >= NumRequiredArgs)
2259 if (ArgNo < FD->getNumParams()) {
2260 const ParmVarDecl *Param = FD->getParamDecl(ArgNo);
2261 if (Param && Param->
hasAttr<MaybeUndefAttr>())
2278 if (llvm::AttributeFuncs::isNoFPClassCompatibleType(IRTy))
2281 if (llvm::StructType *ST = dyn_cast<llvm::StructType>(IRTy)) {
2283 llvm::all_of(ST->elements(), [](llvm::Type *Ty) {
2284 return llvm::AttributeFuncs::isNoFPClassCompatibleType(Ty);
2293 llvm::FPClassTest Mask = llvm::fcNone;
2294 if (LangOpts.NoHonorInfs)
2295 Mask |= llvm::fcInf;
2296 if (LangOpts.NoHonorNaNs)
2297 Mask |= llvm::fcNan;
2303 llvm::AttributeList &Attrs) {
2304 if (Attrs.getMemoryEffects().getModRef() == llvm::ModRefInfo::NoModRef) {
2305 Attrs = Attrs.removeFnAttribute(
getLLVMContext(), llvm::Attribute::Memory);
2306 llvm::Attribute MemoryAttr = llvm::Attribute::getWithMemoryEffects(
2332 llvm::AttributeList &AttrList,
2334 bool AttrOnCallSite,
bool IsThunk) {
2342 FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2344 FuncAttrs.addAttribute(
"cmse_nonsecure_call");
2356 bool HasOptnone =
false;
2358 const NoBuiltinAttr *NBA =
nullptr;
2362 auto AddPotentialArgAccess = [&]() {
2363 llvm::Attribute A = FuncAttrs.getAttribute(llvm::Attribute::Memory);
2365 FuncAttrs.addMemoryAttr(A.getMemoryEffects() |
2366 llvm::MemoryEffects::argMemOnly());
2373 if (TargetDecl->
hasAttr<ReturnsTwiceAttr>())
2374 FuncAttrs.addAttribute(llvm::Attribute::ReturnsTwice);
2375 if (TargetDecl->
hasAttr<NoThrowAttr>())
2376 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2377 if (TargetDecl->
hasAttr<NoReturnAttr>())
2378 FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2379 if (TargetDecl->
hasAttr<ColdAttr>())
2380 FuncAttrs.addAttribute(llvm::Attribute::Cold);
2381 if (TargetDecl->
hasAttr<HotAttr>())
2382 FuncAttrs.addAttribute(llvm::Attribute::Hot);
2383 if (TargetDecl->
hasAttr<NoDuplicateAttr>())
2384 FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate);
2385 if (TargetDecl->
hasAttr<ConvergentAttr>())
2386 FuncAttrs.addAttribute(llvm::Attribute::Convergent);
2388 if (
const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
2391 if (AttrOnCallSite && Fn->isReplaceableGlobalAllocationFunction()) {
2393 auto Kind = Fn->getDeclName().getCXXOverloadedOperator();
2395 (Kind == OO_New || Kind == OO_Array_New))
2396 RetAttrs.addAttribute(llvm::Attribute::NoAlias);
2399 const bool IsVirtualCall = MD && MD->
isVirtual();
2402 if (!(AttrOnCallSite && IsVirtualCall)) {
2403 if (Fn->isNoReturn())
2404 FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2405 NBA = Fn->getAttr<NoBuiltinAttr>();
2409 if (isa<FunctionDecl>(TargetDecl) || isa<VarDecl>(TargetDecl)) {
2412 if (AttrOnCallSite && TargetDecl->
hasAttr<NoMergeAttr>())
2413 FuncAttrs.addAttribute(llvm::Attribute::NoMerge);
2417 if (TargetDecl->
hasAttr<ConstAttr>()) {
2418 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::none());
2419 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2422 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
2423 }
else if (TargetDecl->
hasAttr<PureAttr>()) {
2424 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
2425 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2427 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
2428 }
else if (TargetDecl->
hasAttr<NoAliasAttr>()) {
2429 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::inaccessibleOrArgMemOnly());
2430 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2432 if (TargetDecl->
hasAttr<RestrictAttr>())
2433 RetAttrs.addAttribute(llvm::Attribute::NoAlias);
2434 if (TargetDecl->
hasAttr<ReturnsNonNullAttr>() &&
2435 !CodeGenOpts.NullPointerIsValid)
2436 RetAttrs.addAttribute(llvm::Attribute::NonNull);
2437 if (TargetDecl->
hasAttr<AnyX86NoCallerSavedRegistersAttr>())
2438 FuncAttrs.addAttribute(
"no_caller_saved_registers");
2439 if (TargetDecl->
hasAttr<AnyX86NoCfCheckAttr>())
2440 FuncAttrs.addAttribute(llvm::Attribute::NoCfCheck);
2441 if (TargetDecl->
hasAttr<LeafAttr>())
2442 FuncAttrs.addAttribute(llvm::Attribute::NoCallback);
2444 HasOptnone = TargetDecl->
hasAttr<OptimizeNoneAttr>();
2445 if (
auto *AllocSize = TargetDecl->
getAttr<AllocSizeAttr>()) {
2446 std::optional<unsigned> NumElemsParam;
2447 if (AllocSize->getNumElemsParam().isValid())
2448 NumElemsParam = AllocSize->getNumElemsParam().getLLVMIndex();
2449 FuncAttrs.addAllocSizeAttr(AllocSize->getElemSizeParam().getLLVMIndex(),
2453 if (TargetDecl->
hasAttr<OpenCLKernelAttr>()) {
2456 FuncAttrs.addAttribute(
"uniform-work-group-size",
"true");
2463 FuncAttrs.addAttribute(
2464 "uniform-work-group-size",
2465 llvm::toStringRef(
getLangOpts().OffloadUniformBlock));
2469 if (TargetDecl->
hasAttr<CUDAGlobalAttr>() &&
2471 FuncAttrs.addAttribute(
"uniform-work-group-size",
"true");
2473 if (TargetDecl->
hasAttr<ArmLocallyStreamingAttr>())
2474 FuncAttrs.addAttribute(
"aarch64_pstate_sm_body");
2486 getDefaultFunctionAttributes(Name, HasOptnone, AttrOnCallSite, FuncAttrs);
2491 if (TargetDecl->
hasAttr<NoSpeculativeLoadHardeningAttr>())
2492 FuncAttrs.removeAttribute(llvm::Attribute::SpeculativeLoadHardening);
2493 if (TargetDecl->
hasAttr<SpeculativeLoadHardeningAttr>())
2494 FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
2495 if (TargetDecl->
hasAttr<NoSplitStackAttr>())
2496 FuncAttrs.removeAttribute(
"split-stack");
2497 if (TargetDecl->
hasAttr<ZeroCallUsedRegsAttr>()) {
2500 TargetDecl->
getAttr<ZeroCallUsedRegsAttr>()->getZeroCallUsedRegs();
2501 FuncAttrs.removeAttribute(
"zero-call-used-regs");
2502 FuncAttrs.addAttribute(
2503 "zero-call-used-regs",
2504 ZeroCallUsedRegsAttr::ConvertZeroCallUsedRegsKindToStr(Kind));
2511 if (CodeGenOpts.NoPLT) {
2512 if (
auto *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
2513 if (!Fn->isDefined() && !AttrOnCallSite) {
2514 FuncAttrs.addAttribute(llvm::Attribute::NonLazyBind);
2522 if (TargetDecl && CodeGenOpts.UniqueInternalLinkageNames) {
2523 if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
2524 if (!FD->isExternallyVisible())
2525 FuncAttrs.addAttribute(
"sample-profile-suffix-elision-policy",
2532 if (!AttrOnCallSite) {
2533 if (TargetDecl && TargetDecl->
hasAttr<CmseNSEntryAttr>())
2534 FuncAttrs.addAttribute(
"cmse_nonsecure_entry");
2537 auto shouldDisableTailCalls = [&] {
2539 if (CodeGenOpts.DisableTailCalls)
2545 if (TargetDecl->
hasAttr<DisableTailCallsAttr>() ||
2546 TargetDecl->
hasAttr<AnyX86InterruptAttr>())
2549 if (CodeGenOpts.NoEscapingBlockTailCalls) {
2550 if (
const auto *BD = dyn_cast<BlockDecl>(TargetDecl))
2551 if (!BD->doesNotEscape())
2557 if (shouldDisableTailCalls())
2558 FuncAttrs.addAttribute(
"disable-tail-calls",
"true");
2562 GetCPUAndFeaturesAttributes(CalleeInfo.
getCalleeDecl(), FuncAttrs);
2566 ClangToLLVMArgMapping IRFunctionArgs(
getContext(), FI);
2573 if (CodeGenOpts.EnableNoundefAttrs &&
2577 RetAttrs.addAttribute(llvm::Attribute::NoUndef);
2583 RetAttrs.addAttribute(llvm::Attribute::SExt);
2585 RetAttrs.addAttribute(llvm::Attribute::ZExt);
2589 RetAttrs.addAttribute(llvm::Attribute::InReg);
2601 AddPotentialArgAccess();
2610 llvm_unreachable(
"Invalid ABI kind for return argument");
2618 RetAttrs.addDereferenceableAttr(
2620 if (
getTypes().getTargetAddressSpace(PTy) == 0 &&
2621 !CodeGenOpts.NullPointerIsValid)
2622 RetAttrs.addAttribute(llvm::Attribute::NonNull);
2624 llvm::Align Alignment =
2626 RetAttrs.addAlignmentAttr(Alignment);
2631 bool hasUsedSRet =
false;
2635 if (IRFunctionArgs.hasSRetArg()) {
2637 SRETAttrs.addStructRetAttr(
getTypes().ConvertTypeForMem(RetTy));
2638 SRETAttrs.addAttribute(llvm::Attribute::Writable);
2639 SRETAttrs.addAttribute(llvm::Attribute::DeadOnUnwind);
2642 SRETAttrs.addAttribute(llvm::Attribute::InReg);
2644 ArgAttrs[IRFunctionArgs.getSRetArgNo()] =
2649 if (IRFunctionArgs.hasInallocaArg()) {
2652 ArgAttrs[IRFunctionArgs.getInallocaArgNo()] =
2661 auto IRArgs = IRFunctionArgs.getIRArgs(0);
2663 assert(IRArgs.second == 1 &&
"Expected only a single `this` pointer.");
2670 if (!CodeGenOpts.NullPointerIsValid &&
2672 Attrs.addAttribute(llvm::Attribute::NonNull);
2679 Attrs.addDereferenceableOrNullAttr(
2685 llvm::Align Alignment =
2689 Attrs.addAlignmentAttr(Alignment);
2691 ArgAttrs[IRArgs.first] = llvm::AttributeSet::get(
getLLVMContext(), Attrs);
2697 I != E; ++I, ++ArgNo) {
2703 if (IRFunctionArgs.hasPaddingArg(ArgNo)) {
2705 ArgAttrs[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
2706 llvm::AttributeSet::get(
2708 llvm::AttrBuilder(
getLLVMContext()).addAttribute(llvm::Attribute::InReg));
2713 if (CodeGenOpts.EnableNoundefAttrs &&
2715 Attrs.addAttribute(llvm::Attribute::NoUndef);
2724 Attrs.addAttribute(llvm::Attribute::SExt);
2726 Attrs.addAttribute(llvm::Attribute::ZExt);
2730 Attrs.addAttribute(llvm::Attribute::Nest);
2732 Attrs.addAttribute(llvm::Attribute::InReg);
2733 Attrs.addStackAlignmentAttr(llvm::MaybeAlign(AI.
getDirectAlign()));
2740 Attrs.addAttribute(llvm::Attribute::InReg);
2743 Attrs.addByValAttr(
getTypes().ConvertTypeForMem(ParamType));
2746 if (CodeGenOpts.PassByValueIsNoAlias &&
Decl &&
2747 Decl->getArgPassingRestrictions() ==
2751 Attrs.addAttribute(llvm::Attribute::NoAlias);
2776 AddPotentialArgAccess();
2781 Attrs.addByRefAttr(
getTypes().ConvertTypeForMem(ParamType));
2792 AddPotentialArgAccess();
2799 Attrs.addDereferenceableAttr(
2801 if (
getTypes().getTargetAddressSpace(PTy) == 0 &&
2802 !CodeGenOpts.NullPointerIsValid)
2803 Attrs.addAttribute(llvm::Attribute::NonNull);
2805 llvm::Align Alignment =
2807 Attrs.addAlignmentAttr(Alignment);
2815 if (TargetDecl && TargetDecl->
hasAttr<OpenCLKernelAttr>() &&
2819 llvm::Align Alignment =
2821 Attrs.addAlignmentAttr(Alignment);
2833 Attrs.addStructRetAttr(
getTypes().ConvertTypeForMem(ParamType));
2838 Attrs.addAttribute(llvm::Attribute::NoAlias);
2842 if (!PTy->isIncompleteType() && PTy->isConstantSizeType()) {
2844 Attrs.addDereferenceableAttr(info.Width.getQuantity());
2845 Attrs.addAlignmentAttr(info.Align.getAsAlign());
2851 Attrs.addAttribute(llvm::Attribute::SwiftError);
2855 Attrs.addAttribute(llvm::Attribute::SwiftSelf);
2859 Attrs.addAttribute(llvm::Attribute::SwiftAsync);
2864 Attrs.addAttribute(llvm::Attribute::NoCapture);
2866 if (Attrs.hasAttributes()) {
2867 unsigned FirstIRArg, NumIRArgs;
2868 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
2869 for (
unsigned i = 0; i < NumIRArgs; i++)
2870 ArgAttrs[FirstIRArg + i] = ArgAttrs[FirstIRArg + i].addAttributes(
2876 AttrList = llvm::AttributeList::get(
2885 llvm::Value *value) {
2890 if (value->getType() == varType)
return value;
2892 assert((varType->isIntegerTy() || varType->isFloatingPointTy())
2893 &&
"unexpected promotion type");
2895 if (isa<llvm::IntegerType>(varType))
2896 return CGF.
Builder.CreateTrunc(value, varType,
"arg.unpromote");
2898 return CGF.
Builder.CreateFPCast(value, varType,
"arg.unpromote");
2904 QualType ArgType,
unsigned ArgNo) {
2916 if (
auto ParmNNAttr = PVD->
getAttr<NonNullAttr>())
2923 if (NNAttr->isNonNull(ArgNo))
2953 if (FD->hasImplicitReturnZero()) {
2954 QualType RetTy = FD->getReturnType().getUnqualifiedType();
2956 llvm::Constant*
Zero = llvm::Constant::getNullValue(LLVMTy);
2965 assert(Fn->arg_size() == IRFunctionArgs.totalIRArgs());
2970 if (IRFunctionArgs.hasInallocaArg())
2971 ArgStruct =
Address(Fn->getArg(IRFunctionArgs.getInallocaArgNo()),
2975 if (IRFunctionArgs.hasSRetArg()) {
2976 auto AI = Fn->getArg(IRFunctionArgs.getSRetArgNo());
2977 AI->setName(
"agg.result");
2978 AI->addAttr(llvm::Attribute::NoAlias);
2985 ArgVals.reserve(Args.size());
2991 assert(FI.
arg_size() == Args.size() &&
2992 "Mismatch between function signature & arguments.");
2995 for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
2996 i != e; ++i, ++info_it, ++ArgNo) {
3001 isa<ParmVarDecl>(Arg) && cast<ParmVarDecl>(Arg)->isKNRPromoted();
3009 unsigned FirstIRArg, NumIRArgs;
3010 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
3014 assert(NumIRArgs == 0);
3027 assert(NumIRArgs == 1);
3051 ParamAddr = AlignedTemp;
3068 auto AI = Fn->getArg(FirstIRArg);
3076 assert(NumIRArgs == 1);
3078 if (
const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(Arg)) {
3081 PVD->getFunctionScopeIndex()) &&
3083 AI->addAttr(llvm::Attribute::NonNull);
3085 QualType OTy = PVD->getOriginalType();
3086 if (
const auto *ArrTy =
3093 QualType ETy = ArrTy->getElementType();
3094 llvm::Align Alignment =
3096 AI->addAttrs(llvm::AttrBuilder(
getLLVMContext()).addAlignmentAttr(Alignment));
3097 uint64_t ArrSize = ArrTy->getZExtSize();
3101 Attrs.addDereferenceableAttr(
3102 getContext().getTypeSizeInChars(ETy).getQuantity() *
3104 AI->addAttrs(Attrs);
3105 }
else if (
getContext().getTargetInfo().getNullPointerValue(
3108 AI->addAttr(llvm::Attribute::NonNull);
3111 }
else if (
const auto *ArrTy =
3117 QualType ETy = ArrTy->getElementType();
3118 llvm::Align Alignment =
3120 AI->addAttrs(llvm::AttrBuilder(
getLLVMContext()).addAlignmentAttr(Alignment));
3121 if (!
getTypes().getTargetAddressSpace(ETy) &&
3123 AI->addAttr(llvm::Attribute::NonNull);
3128 const auto *AVAttr = PVD->getAttr<AlignValueAttr>();
3131 AVAttr = TOTy->getDecl()->getAttr<AlignValueAttr>();
3132 if (AVAttr && !
SanOpts.
has(SanitizerKind::Alignment)) {
3136 llvm::ConstantInt *AlignmentCI =
3139 AlignmentCI->getLimitedValue(llvm::Value::MaximumAlignment);
3140 if (AI->getParamAlign().valueOrOne() < AlignmentInt) {
3141 AI->removeAttr(llvm::Attribute::AttrKind::Alignment);
3142 AI->addAttrs(llvm::AttrBuilder(
getLLVMContext()).addAlignmentAttr(
3143 llvm::Align(AlignmentInt)));
3150 AI->addAttr(llvm::Attribute::NoAlias);
3158 assert(NumIRArgs == 1);
3162 llvm::Value *
V = AI;
3170 V, pointeeTy,
getContext().getTypeAlignInChars(pointeeTy));
3193 if (
V->getType() != LTy)
3204 if (
auto *VecTyTo = dyn_cast<llvm::FixedVectorType>(
ConvertType(Ty))) {
3205 llvm::Value *Coerced = Fn->getArg(FirstIRArg);
3206 if (
auto *VecTyFrom =
3207 dyn_cast<llvm::ScalableVectorType>(Coerced->getType())) {
3210 if (VecTyFrom->getElementType()->isIntegerTy(1) &&
3211 VecTyFrom->getElementCount().isKnownMultipleOf(8) &&
3212 VecTyTo->getElementType() ==
Builder.getInt8Ty()) {
3213 VecTyFrom = llvm::ScalableVectorType::get(
3214 VecTyTo->getElementType(),
3215 VecTyFrom->getElementCount().getKnownMinValue() / 8);
3216 Coerced =
Builder.CreateBitCast(Coerced, VecTyFrom);
3218 if (VecTyFrom->getElementType() == VecTyTo->getElementType()) {
3221 assert(NumIRArgs == 1);
3222 Coerced->setName(Arg->
getName() +
".coerce");
3224 VecTyTo, Coerced, Zero,
"cast.fixed")));
3230 llvm::StructType *STy =
3233 STy->getNumElements() > 1) {
3234 [[maybe_unused]] llvm::TypeSize StructSize =
3236 [[maybe_unused]] llvm::TypeSize PtrElementSize =
3238 if (STy->containsHomogeneousScalableVectorTypes()) {
3239 assert(StructSize == PtrElementSize &&
3240 "Only allow non-fractional movement of structure with"
3241 "homogeneous scalable vector type");
3257 STy->getNumElements() > 1) {
3259 llvm::TypeSize PtrElementSize =
3261 if (StructSize.isScalable()) {
3262 assert(STy->containsHomogeneousScalableVectorTypes() &&
3263 "ABI only supports structure with homogeneous scalable vector "
3265 assert(StructSize == PtrElementSize &&
3266 "Only allow non-fractional movement of structure with"
3267 "homogeneous scalable vector type");
3268 assert(STy->getNumElements() == NumIRArgs);
3270 llvm::Value *LoadedStructValue = llvm::PoisonValue::get(STy);
3271 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
3272 auto *AI = Fn->getArg(FirstIRArg + i);
3273 AI->setName(Arg->
getName() +
".coerce" + Twine(i));
3275 Builder.CreateInsertValue(LoadedStructValue, AI, i);
3280 uint64_t SrcSize = StructSize.getFixedValue();
3281 uint64_t DstSize = PtrElementSize.getFixedValue();
3284 if (SrcSize <= DstSize) {
3291 assert(STy->getNumElements() == NumIRArgs);
3292 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
3293 auto AI = Fn->getArg(FirstIRArg + i);
3294 AI->setName(Arg->
getName() +
".coerce" + Twine(i));
3299 if (SrcSize > DstSize) {
3305 assert(NumIRArgs == 1);
3306 auto AI = Fn->getArg(FirstIRArg);
3307 AI->setName(Arg->
getName() +
".coerce");
3332 unsigned argIndex = FirstIRArg;
3333 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
3334 llvm::Type *eltType = coercionType->getElementType(i);
3339 auto elt = Fn->getArg(argIndex++);
3342 assert(argIndex == FirstIRArg + NumIRArgs);
3354 auto FnArgIter = Fn->arg_begin() + FirstIRArg;
3355 ExpandTypeFromArgs(Ty, LV, FnArgIter);
3356 assert(FnArgIter == Fn->arg_begin() + FirstIRArg + NumIRArgs);
3357 for (
unsigned i = 0, e = NumIRArgs; i != e; ++i) {
3358 auto AI = Fn->getArg(FirstIRArg + i);
3359 AI->setName(Arg->
getName() +
"." + Twine(i));
3365 assert(NumIRArgs == 0);
3377 if (
getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) {
3378 for (
int I = Args.size() - 1; I >= 0; --I)
3381 for (
unsigned I = 0, E = Args.size(); I != E; ++I)
3387 while (insn->use_empty()) {
3388 llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(insn);
3389 if (!bitcast)
return;
3392 insn = cast<llvm::Instruction>(bitcast->getOperand(0));
3393 bitcast->eraseFromParent();
3399 llvm::Value *result) {
3401 llvm::BasicBlock *BB = CGF.
Builder.GetInsertBlock();
3402 if (BB->empty())
return nullptr;
3403 if (&BB->back() != result)
return nullptr;
3405 llvm::Type *resultType = result->getType();
3408 llvm::Instruction *generator = cast<llvm::Instruction>(result);
3414 while (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(generator)) {
3417 generator = cast<llvm::Instruction>(bitcast->getOperand(0));
3420 if (generator->getNextNode() != bitcast)
3423 InstsToKill.push_back(bitcast);
3430 llvm::CallInst *call = dyn_cast<llvm::CallInst>(generator);
3431 if (!call)
return nullptr;
3433 bool doRetainAutorelease;
3436 doRetainAutorelease =
true;
3437 }
else if (call->getCalledOperand() ==
3439 doRetainAutorelease =
false;
3447 llvm::Instruction *prev = call->getPrevNode();
3449 if (isa<llvm::BitCastInst>(prev)) {
3450 prev = prev->getPrevNode();
3453 assert(isa<llvm::CallInst>(prev));
3454 assert(cast<llvm::CallInst>(prev)->getCalledOperand() ==
3456 InstsToKill.push_back(prev);
3462 result = call->getArgOperand(0);
3463 InstsToKill.push_back(call);
3467 while (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(result)) {
3468 if (!bitcast->hasOneUse())
break;
3469 InstsToKill.push_back(bitcast);
3470 result = bitcast->getOperand(0);
3474 for (
auto *I : InstsToKill)
3475 I->eraseFromParent();
3478 if (doRetainAutorelease)
3482 return CGF.
Builder.CreateBitCast(result, resultType);
3487 llvm::Value *result) {
3490 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurCodeDecl);
3491 if (!method)
return nullptr;
3497 llvm::CallInst *retainCall = dyn_cast<llvm::CallInst>(result);
3498 if (!retainCall || retainCall->getCalledOperand() !=
3503 llvm::Value *retainedValue = retainCall->getArgOperand(0);
3504 llvm::LoadInst *load =
3505 dyn_cast<llvm::LoadInst>(retainedValue->stripPointerCasts());
3506 if (!load || load->isAtomic() || load->isVolatile() ||
3513 llvm::Type *resultType = result->getType();
3515 assert(retainCall->use_empty());
3516 retainCall->eraseFromParent();
3519 return CGF.
Builder.CreateBitCast(load, resultType);
3526 llvm::Value *result) {
3549 auto GetStoreIfValid = [&CGF,
3550 ReturnValuePtr](llvm::User *
U) -> llvm::StoreInst * {
3551 auto *SI = dyn_cast<llvm::StoreInst>(
U);
3552 if (!SI || SI->getPointerOperand() != ReturnValuePtr ||
3558 assert(!SI->isAtomic() &&
3566 if (!ReturnValuePtr->hasOneUse()) {
3567 llvm::BasicBlock *IP = CGF.
Builder.GetInsertBlock();
3568 if (IP->empty())
return nullptr;
3572 for (llvm::Instruction &I : make_range(IP->rbegin(), IP->rend())) {
3573 if (isa<llvm::BitCastInst>(&I))
3575 if (
auto *II = dyn_cast<llvm::IntrinsicInst>(&I))
3576 if (II->getIntrinsicID() == llvm::Intrinsic::lifetime_end)
3579 return GetStoreIfValid(&I);
3584 llvm::StoreInst *store = GetStoreIfValid(ReturnValuePtr->user_back());
3585 if (!store)
return nullptr;
3589 llvm::BasicBlock *StoreBB = store->getParent();
3590 llvm::BasicBlock *IP = CGF.
Builder.GetInsertBlock();
3592 while (IP != StoreBB) {
3593 if (!SeenBBs.insert(IP).second || !(IP = IP->getSinglePredecessor()))
3609 int BitWidth,
int CharWidth) {
3610 assert(CharWidth <= 64);
3611 assert(
static_cast<unsigned>(BitWidth) <= Bits.size() * CharWidth);
3614 if (BitOffset >= CharWidth) {
3615 Pos += BitOffset / CharWidth;
3616 BitOffset = BitOffset % CharWidth;
3619 const uint64_t
Used = (uint64_t(1) << CharWidth) - 1;
3620 if (BitOffset + BitWidth >= CharWidth) {
3621 Bits[Pos++] |= (
Used << BitOffset) &
Used;
3622 BitWidth -= CharWidth - BitOffset;
3626 while (BitWidth >= CharWidth) {
3628 BitWidth -= CharWidth;
3632 Bits[Pos++] |= (
Used >> (CharWidth - BitWidth)) << BitOffset;
3640 int StorageSize,
int BitOffset,
int BitWidth,
3641 int CharWidth,
bool BigEndian) {
3644 setBitRange(TmpBits, BitOffset, BitWidth, CharWidth);
3647 std::reverse(TmpBits.begin(), TmpBits.end());
3649 for (uint64_t
V : TmpBits)
3650 Bits[StorageOffset++] |=
V;
3681 BFI.
Size, CharWidth,
3703 auto Src = TmpBits.begin();
3704 auto Dst = Bits.begin() + Offset + I * Size;
3705 for (
int J = 0; J < Size; ++J)
3725 std::fill_n(Bits.begin() + Offset, Size,
3730 int Pos,
int Size,
int CharWidth,
3735 for (
auto P = Bits.begin() + Pos, E = Bits.begin() + Pos + Size;
P != E;
3737 Mask = (Mask << CharWidth) | *
P;
3739 auto P = Bits.begin() + Pos + Size, End = Bits.begin() + Pos;
3741 Mask = (Mask << CharWidth) | *--
P;
3750 llvm::IntegerType *ITy,
3752 assert(Src->getType() == ITy);
3753 assert(ITy->getScalarSizeInBits() <= 64);
3756 int Size = DataLayout.getTypeStoreSize(ITy);
3764 return Builder.CreateAnd(Src, Mask,
"cmse.clear");
3770 llvm::ArrayType *ATy,
3773 int Size = DataLayout.getTypeStoreSize(ATy);
3780 ATy->getArrayElementType()->getScalarSizeInBits() / CharWidth;
3782 llvm::Value *R = llvm::PoisonValue::get(ATy);
3783 for (
int I = 0, N = ATy->getArrayNumElements(); I != N; ++I) {
3785 DataLayout.isBigEndian());
3786 MaskIndex += CharsPerElt;
3787 llvm::Value *T0 =
Builder.CreateExtractValue(Src, I);
3788 llvm::Value *T1 =
Builder.CreateAnd(T0, Mask,
"cmse.clear");
3789 R =
Builder.CreateInsertValue(R, T1, I);
3816 llvm::DebugLoc RetDbgLoc;
3817 llvm::Value *RV =
nullptr;
3827 llvm::Function::arg_iterator EI =
CurFn->arg_end();
3829 llvm::Value *ArgStruct = &*EI;
3833 cast<llvm::GetElementPtrInst>(SRet)->getResultElementType();
3839 auto AI =
CurFn->arg_begin();
3878 if (llvm::StoreInst *SI =
3884 RetDbgLoc = SI->getDebugLoc();
3886 RV = SI->getValueOperand();
3887 SI->eraseFromParent();
3910 if (
auto *FD = dyn_cast<FunctionDecl>(
CurCodeDecl))
3911 RT = FD->getReturnType();
3912 else if (
auto *MD = dyn_cast<ObjCMethodDecl>(
CurCodeDecl))
3913 RT = MD->getReturnType();
3917 llvm_unreachable(
"Unexpected function/method type");
3937 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
3944 results.push_back(elt);
3948 if (results.size() == 1) {
3956 RV = llvm::PoisonValue::get(returnType);
3957 for (
unsigned i = 0, e = results.size(); i != e; ++i) {
3958 RV =
Builder.CreateInsertValue(RV, results[i], i);
3965 llvm_unreachable(
"Invalid ABI kind for return argument");
3968 llvm::Instruction *
Ret;
3974 auto *ITy = dyn_cast<llvm::IntegerType>(RV->getType());
3985 Ret->setDebugLoc(std::move(RetDbgLoc));
3998 ReturnsNonNullAttr *RetNNAttr =
nullptr;
3999 if (
SanOpts.
has(SanitizerKind::ReturnsNonnullAttribute))
4002 if (!RetNNAttr && !requiresReturnValueNullabilityCheck())
4010 assert(!requiresReturnValueNullabilityCheck() &&
4011 "Cannot check nullability and the nonnull attribute");
4012 AttrLoc = RetNNAttr->getLocation();
4013 CheckKind = SanitizerKind::ReturnsNonnullAttribute;
4014 Handler = SanitizerHandler::NonnullReturn;
4016 if (
auto *DD = dyn_cast<DeclaratorDecl>(
CurCodeDecl))
4017 if (
auto *TSI = DD->getTypeSourceInfo())
4019 AttrLoc = FTL.getReturnLoc().findNullabilityLoc();
4020 CheckKind = SanitizerKind::NullabilityReturn;
4021 Handler = SanitizerHandler::NullabilityReturn;
4024 SanitizerScope SanScope(
this);
4031 llvm::Value *CanNullCheck =
Builder.CreateIsNotNull(SLocPtr);
4032 if (requiresReturnValueNullabilityCheck())
4034 Builder.CreateAnd(CanNullCheck, RetValNullabilityPrecondition);
4035 Builder.CreateCondBr(CanNullCheck, Check, NoCheck);
4039 llvm::Value *Cond =
Builder.CreateIsNotNull(RV);
4041 llvm::Value *DynamicData[] = {SLocPtr};
4042 EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, DynamicData);
4062 llvm::Type *IRPtrTy = llvm::PointerType::getUnqual(CGF.
getLLVMContext());
4063 llvm::Value *Placeholder = llvm::PoisonValue::get(IRPtrTy);
4090 if (
type->isReferenceType()) {
4099 param->
hasAttr<NSConsumedAttr>() &&
4100 type->isObjCRetainableType()) {
4103 llvm::ConstantPointerNull::get(cast<llvm::PointerType>(ptr->getType()));
4118 CalleeDestructedParamCleanups.lookup(cast<ParmVarDecl>(param));
4120 "cleanup for callee-destructed param not recorded");
4122 llvm::Instruction *isActive =
Builder.CreateUnreachable();
4128 return llvm::isa_and_nonnull<llvm::ConstantPointerNull>(addr);
4141 "shouldn't have writeback for provably null argument");
4143 llvm::BasicBlock *contBB =
nullptr;
4149 if (!provablyNonNull) {
4154 CGF.
Builder.CreateCondBr(isNull, contBB, writebackBB);
4163 "icr.writeback-cast");
4172 if (writeback.
ToUse) {
4197 if (!provablyNonNull)
4212 for (
const auto &I : llvm::reverse(Cleanups)) {
4214 I.IsActiveIP->eraseFromParent();
4220 if (uop->getOpcode() == UO_AddrOf)
4221 return uop->getSubExpr();
4251 llvm::PointerType *destType =
4253 llvm::Type *destElemType =
4270 CodeGenFunction::ConditionalEvaluation condEval(CGF);
4276 llvm::ConstantPointerNull::get(cast<llvm::PointerType>(destElemType));
4280 llvm::BasicBlock *contBB =
nullptr;
4281 llvm::BasicBlock *originBB =
nullptr;
4284 llvm::Value *finalArgument;
4288 if (provablyNonNull) {
4293 finalArgument = CGF.
Builder.CreateSelect(
4294 isNull, llvm::ConstantPointerNull::get(destType),
4300 originBB = CGF.
Builder.GetInsertBlock();
4303 CGF.
Builder.CreateCondBr(isNull, contBB, copyBB);
4305 condEval.begin(CGF);
4309 llvm::Value *valueToUse =
nullptr;
4317 src = CGF.
Builder.CreateBitCast(src, destElemType,
"icr.cast");
4334 if (shouldCopy && !provablyNonNull) {
4335 llvm::BasicBlock *copyBB = CGF.
Builder.GetInsertBlock();
4340 llvm::PHINode *phiToUse = CGF.
Builder.CreatePHI(valueToUse->getType(), 2,
4342 phiToUse->addIncoming(valueToUse, copyBB);
4343 phiToUse->addIncoming(llvm::UndefValue::get(valueToUse->getType()),
4345 valueToUse = phiToUse;
4359 StackBase = CGF.
Builder.CreateStackSave(
"inalloca.save");
4365 CGF.
Builder.CreateStackRestore(StackBase);
4373 if (!AC.getDecl() || !(
SanOpts.
has(SanitizerKind::NonnullAttribute) ||
4378 auto PVD = ParmNum < AC.getNumParams() ? AC.getParamDecl(ParmNum) :
nullptr;
4379 unsigned ArgNo = PVD ? PVD->getFunctionScopeIndex() : ParmNum;
4382 const NonNullAttr *NNAttr =
nullptr;
4383 if (
SanOpts.
has(SanitizerKind::NonnullAttribute))
4386 bool CanCheckNullability =
false;
4387 if (
SanOpts.
has(SanitizerKind::NullabilityArg) && !NNAttr && PVD &&
4388 !PVD->getType()->isRecordType()) {
4389 auto Nullability = PVD->getType()->getNullability();
4390 CanCheckNullability = Nullability &&
4392 PVD->getTypeSourceInfo();
4395 if (!NNAttr && !CanCheckNullability)
4402 AttrLoc = NNAttr->getLocation();
4403 CheckKind = SanitizerKind::NonnullAttribute;
4404 Handler = SanitizerHandler::NonnullArg;
4406 AttrLoc = PVD->getTypeSourceInfo()->getTypeLoc().findNullabilityLoc();
4407 CheckKind = SanitizerKind::NullabilityArg;
4408 Handler = SanitizerHandler::NullabilityArg;
4411 SanitizerScope SanScope(
this);
4413 llvm::Constant *StaticData[] = {
4415 llvm::ConstantInt::get(
Int32Ty, ArgNo + 1),
4417 EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, std::nullopt);
4422 AbstractCallee AC,
unsigned ParmNum) {
4423 if (!AC.getDecl() || !(
SanOpts.
has(SanitizerKind::NonnullAttribute) ||
4443 return llvm::any_of(ArgTypes, [&](
QualType Ty) {
4454 return classDecl->getTypeParamListAsWritten();
4458 return catDecl->getTypeParamList();
4468 llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
4469 AbstractCallee AC,
unsigned ParamsToSkip, EvaluationOrder Order) {
4472 assert((ParamsToSkip == 0 ||
Prototype.P) &&
4473 "Can't skip parameters if type info is not provided");
4483 bool IsVariadic =
false;
4490 ArgTypes.assign(MD->param_type_begin() + ParamsToSkip,
4491 MD->param_type_end());
4495 ExplicitCC = FPT->getExtInfo().getCC();
4496 ArgTypes.assign(FPT->param_type_begin() + ParamsToSkip,
4497 FPT->param_type_end());
4505 assert(Arg != ArgRange.end() &&
"Running over edge of argument list!");
4507 (isGenericMethod || Ty->isVariablyModifiedType() ||
4508 Ty.getNonReferenceType()->isObjCRetainableType() ||
4510 .getCanonicalType(Ty.getNonReferenceType())
4512 getContext().getCanonicalType((*Arg)->getType()).getTypePtr()) &&
4513 "type mismatch in call argument!");
4519 assert((Arg == ArgRange.end() || IsVariadic) &&
4520 "Extra arguments in non-variadic function!");
4525 for (
auto *A : llvm::drop_begin(ArgRange, ArgTypes.size()))
4526 ArgTypes.push_back(IsVariadic ? getVarArgType(A) : A->getType());
4527 assert((
int)ArgTypes.size() == (ArgRange.end() - ArgRange.begin()));
4539 auto MaybeEmitImplicitObjectSize = [&](
unsigned I,
const Expr *Arg,
4541 if (!AC.hasFunctionDecl() || I >= AC.getNumParams())
4543 auto *PS = AC.getParamDecl(I)->getAttr<PassObjectSizeAttr>();
4550 assert(EmittedArg.getScalarVal() &&
"We emitted nothing for the arg?");
4551 llvm::Value *
V = evaluateOrEmitBuiltinObjectSize(Arg, PS->getType(),
T,
4552 EmittedArg.getScalarVal(),
4558 std::swap(Args.back(), *(&Args.back() - 1));
4563 assert(
getTarget().getTriple().getArch() == llvm::Triple::x86 &&
4564 "inalloca only supported on x86");
4569 size_t CallArgsStart = Args.size();
4570 for (
unsigned I = 0, E = ArgTypes.size(); I != E; ++I) {
4571 unsigned Idx = LeftToRight ? I : E - I - 1;
4573 unsigned InitialArgSize = Args.size();
4576 assert((!isa<ObjCIndirectCopyRestoreExpr>(*Arg) ||
4577 getContext().hasSameUnqualifiedType((*Arg)->getType(),
4579 (isa<ObjCMethodDecl>(AC.getDecl()) &&
4581 "Argument and parameter types don't match");
4585 assert(InitialArgSize + 1 == Args.size() &&
4586 "The code below depends on only adding one arg per EmitCallArg");
4587 (void)InitialArgSize;
4590 if (!Args.back().hasLValue()) {
4591 RValue RVArg = Args.back().getKnownRValue();
4593 ParamsToSkip + Idx);
4597 MaybeEmitImplicitObjectSize(Idx, *Arg, RVArg);
4604 std::reverse(Args.begin() + CallArgsStart, Args.end());
4612 : Addr(Addr), Ty(Ty) {}
4630struct DisableDebugLocationUpdates {
4632 bool disabledDebugInfo;
4634 if ((disabledDebugInfo = isa<CXXDefaultArgExpr>(E) && CGF.
getDebugInfo()))
4637 ~DisableDebugLocationUpdates() {
4638 if (disabledDebugInfo)
4674 DisableDebugLocationUpdates Dis(*
this, E);
4676 = dyn_cast<ObjCIndirectCopyRestoreExpr>(E)) {
4682 "reference binding to unmaterialized r-value!");
4694 if (
type->isRecordType() &&
4701 bool DestroyedInCallee =
true, NeedsEHCleanup =
true;
4702 if (
const auto *RD =
type->getAsCXXRecordDecl())
4703 DestroyedInCallee = RD->hasNonTrivialDestructor();
4707 if (DestroyedInCallee)
4714 if (DestroyedInCallee && NeedsEHCleanup) {
4721 llvm::Instruction *IsActive =
Builder.CreateUnreachable();
4727 if (HasAggregateEvalKind && isa<ImplicitCastExpr>(E) &&
4728 cast<CastExpr>(E)->getCastKind() == CK_LValueToRValue &&
4729 !
type->isArrayParameterType()) {
4739QualType CodeGenFunction::getVarArgType(
const Expr *Arg) {
4743 if (!
getTarget().getTriple().isOSWindows())
4760CodeGenFunction::AddObjCARCExceptionMetadata(llvm::Instruction *Inst) {
4763 Inst->setMetadata(
"clang.arc.no_objc_arc_exceptions",
4770 const llvm::Twine &name) {
4778 const llvm::Twine &name) {
4780 for (
auto arg : args)
4781 values.push_back(
arg.emitRawPointer(*
this));
4788 const llvm::Twine &name) {
4790 call->setDoesNotThrow();
4797 const llvm::Twine &name) {
4812 if (
auto *CalleeFn = dyn_cast<llvm::Function>(
Callee->stripPointerCasts())) {
4813 if (CalleeFn->isIntrinsic() && CalleeFn->doesNotThrow()) {
4814 auto IID = CalleeFn->getIntrinsicID();
4815 if (!llvm::IntrinsicInst::mayLowerToFunctionCall(IID))
4828 const llvm::Twine &name) {
4829 llvm::CallInst *call =
Builder.CreateCall(
4842 llvm::InvokeInst *invoke =
4848 invoke->setDoesNotReturn();
4851 llvm::CallInst *call =
Builder.CreateCall(callee, args, BundleList);
4852 call->setDoesNotReturn();
4861 const Twine &name) {
4869 const Twine &name) {
4879 const Twine &Name) {
4884 llvm::CallBase *Inst;
4886 Inst =
Builder.CreateCall(Callee, Args, BundleList, Name);
4889 Inst =
Builder.CreateInvoke(Callee, ContBB, InvokeDest, Args, BundleList,
4897 AddObjCARCExceptionMetadata(Inst);
4902void CodeGenFunction::deferPlaceholderReplacement(llvm::Instruction *Old,
4904 DeferredReplacements.push_back(
4905 std::make_pair(llvm::WeakTrackingVH(Old), New));
4912[[nodiscard]] llvm::AttributeList
4913maybeRaiseRetAlignmentAttribute(llvm::LLVMContext &Ctx,
4914 const llvm::AttributeList &Attrs,
4915 llvm::Align NewAlign) {
4916 llvm::Align CurAlign = Attrs.getRetAlignment().valueOrOne();
4917 if (CurAlign >= NewAlign)
4919 llvm::Attribute AlignAttr = llvm::Attribute::getWithAlignment(Ctx, NewAlign);
4920 return Attrs.removeRetAttribute(Ctx, llvm::Attribute::AttrKind::Alignment)
4921 .addRetAttribute(Ctx, AlignAttr);
4924template <
typename AlignedAttrTy>
class AbstractAssumeAlignedAttrEmitter {
4929 const AlignedAttrTy *AA =
nullptr;
4931 llvm::Value *Alignment =
nullptr;
4932 llvm::ConstantInt *OffsetCI =
nullptr;
4938 AA = FuncDecl->
getAttr<AlignedAttrTy>();
4943 [[nodiscard]] llvm::AttributeList
4944 TryEmitAsCallSiteAttribute(
const llvm::AttributeList &Attrs) {
4945 if (!AA || OffsetCI || CGF.
SanOpts.
has(SanitizerKind::Alignment))
4947 const auto *AlignmentCI = dyn_cast<llvm::ConstantInt>(Alignment);
4952 if (!AlignmentCI->getValue().isPowerOf2())
4954 llvm::AttributeList NewAttrs = maybeRaiseRetAlignmentAttribute(
4957 AlignmentCI->getLimitedValue(llvm::Value::MaximumAlignment)));
4969 AA->getLocation(), Alignment, OffsetCI);
4975class AssumeAlignedAttrEmitter final
4976 :
public AbstractAssumeAlignedAttrEmitter<AssumeAlignedAttr> {
4979 : AbstractAssumeAlignedAttrEmitter(CGF_, FuncDecl) {
4983 Alignment = cast<llvm::ConstantInt>(CGF.
EmitScalarExpr(AA->getAlignment()));
4984 if (
Expr *Offset = AA->getOffset()) {
4986 if (OffsetCI->isNullValue())
4993class AllocAlignAttrEmitter final
4994 :
public AbstractAssumeAlignedAttrEmitter<AllocAlignAttr> {
4998 : AbstractAssumeAlignedAttrEmitter(CGF_, FuncDecl) {
5002 Alignment = CallArgs[AA->getParamIndex().getLLVMIndex()]
5011 if (
auto *VT = dyn_cast<llvm::VectorType>(Ty))
5012 return VT->getPrimitiveSizeInBits().getKnownMinValue();
5013 if (
auto *AT = dyn_cast<llvm::ArrayType>(Ty))
5016 unsigned MaxVectorWidth = 0;
5017 if (
auto *ST = dyn_cast<llvm::StructType>(Ty))
5018 for (
auto *I : ST->elements())
5020 return MaxVectorWidth;
5027 llvm::CallBase **callOrInvoke,
bool IsMustTail,
5040 const Decl *TargetDecl =
Callee.getAbstractInfo().getCalleeDecl().getDecl();
5041 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
5048 if (TargetDecl->
hasAttr<AlwaysInlineAttr>() &&
5049 (TargetDecl->
hasAttr<TargetAttr>() ||
5056 CGM, Loc, dyn_cast_or_null<FunctionDecl>(
CurCodeDecl), FD, CallArgs);
5064 if (llvm::StructType *ArgStruct = CallInfo.
getArgStruct()) {
5067 llvm::AllocaInst *AI;
5069 IP = IP->getNextNode();
5070 AI =
new llvm::AllocaInst(ArgStruct, DL.getAllocaAddrSpace(),
5076 AI->setAlignment(Align.getAsAlign());
5077 AI->setUsedWithInAlloca(
true);
5078 assert(AI->isUsedWithInAlloca() && !AI->isStaticAlloca());
5079 ArgMemory =
RawAddress(AI, ArgStruct, Align);
5082 ClangToLLVMArgMapping IRFunctionArgs(
CGM.
getContext(), CallInfo);
5089 llvm::Value *UnusedReturnSizePtr =
nullptr;
5096 llvm::TypeSize size =
5101 if (IRFunctionArgs.hasSRetArg()) {
5102 IRCallArgs[IRFunctionArgs.getSRetArgNo()] =
5120 assert(CallInfo.
arg_size() == CallArgs.size() &&
5121 "Mismatch between function signature & arguments.");
5124 for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end();
5125 I != E; ++I, ++info_it, ++ArgNo) {
5129 if (IRFunctionArgs.hasPaddingArg(ArgNo))
5130 IRCallArgs[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
5133 unsigned FirstIRArg, NumIRArgs;
5134 std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
5136 bool ArgHasMaybeUndefAttr =
5141 assert(NumIRArgs == 0);
5142 assert(
getTarget().getTriple().getArch() == llvm::Triple::x86);
5143 if (I->isAggregate()) {
5145 ? I->getKnownLValue().getAddress(*
this)
5146 : I->getKnownRValue().getAggregateAddress();
5147 llvm::Instruction *Placeholder =
5152 CGBuilderTy::InsertPoint IP =
Builder.saveIP();
5153 Builder.SetInsertPoint(Placeholder);
5166 deferPlaceholderReplacement(Placeholder, Addr.
getPointer());
5171 I->Ty,
getContext().getTypeAlignInChars(I->Ty),
5172 "indirect-arg-temp");
5173 I->copyInto(*
this, Addr);
5182 I->copyInto(*
this, Addr);
5189 assert(NumIRArgs == 1);
5190 if (!I->isAggregate()) {
5196 if (ArgHasMaybeUndefAttr)
5197 Val =
Builder.CreateFreeze(Val);
5198 IRCallArgs[FirstIRArg] = Val;
5200 I->copyInto(*
this, Addr);
5211 ? I->getKnownLValue().getAddress(*
this)
5212 : I->getKnownRValue().getAggregateAddress();
5216 assert((FirstIRArg >= IRFuncTy->getNumParams() ||
5217 IRFuncTy->getParamType(FirstIRArg)->getPointerAddressSpace() ==
5218 TD->getAllocaAddrSpace()) &&
5219 "indirect argument must be in alloca address space");
5221 bool NeedCopy =
false;
5227 }
else if (I->hasLValue()) {
5228 auto LV = I->getKnownLValue();
5234 if (!isByValOrRef ||
5239 if ((isByValOrRef &&
5247 else if ((isByValOrRef &&
5248 Addr.
getType()->getAddressSpace() != IRFuncTy->
5259 if (ArgHasMaybeUndefAttr)
5260 Val =
Builder.CreateFreeze(Val);
5261 IRCallArgs[FirstIRArg] = Val;
5264 llvm::TypeSize ByvalTempElementSize =
5266 llvm::Value *LifetimeSize =
5271 CallLifetimeEndAfterCall.emplace_back(AI, LifetimeSize);
5274 I->copyInto(*
this, AI);
5278 auto *
T = llvm::PointerType::get(
5284 if (ArgHasMaybeUndefAttr)
5285 Val =
Builder.CreateFreeze(Val);
5286 IRCallArgs[FirstIRArg] = Val;
5293 assert(NumIRArgs == 0);
5301 assert(NumIRArgs == 1);
5303 if (!I->isAggregate())
5304 V = I->getKnownRValue().getScalarVal();
5307 I->hasLValue() ? I->getKnownLValue().getAddress(*
this)
5308 : I->getKnownRValue().getAggregateAddress());
5314 assert(!swiftErrorTemp.
isValid() &&
"multiple swifterror args");
5318 V, pointeeTy,
getContext().getTypeAlignInChars(pointeeTy));
5323 cast<llvm::AllocaInst>(
V)->setSwiftError(
true);
5331 V->getType()->isIntegerTy())
5336 if (FirstIRArg < IRFuncTy->getNumParams() &&
5337 V->getType() != IRFuncTy->getParamType(FirstIRArg))
5338 V =
Builder.CreateBitCast(
V, IRFuncTy->getParamType(FirstIRArg));
5340 if (ArgHasMaybeUndefAttr)
5342 IRCallArgs[FirstIRArg] =
V;
5346 llvm::StructType *STy =
5350 [[maybe_unused]] llvm::TypeSize SrcTypeSize =
5352 [[maybe_unused]] llvm::TypeSize DstTypeSize =
5354 if (STy->containsHomogeneousScalableVectorTypes()) {
5355 assert(SrcTypeSize == DstTypeSize &&
5356 "Only allow non-fractional movement of structure with "
5357 "homogeneous scalable vector type");
5359 IRCallArgs[FirstIRArg] = I->getKnownRValue().getScalarVal();
5366 if (!I->isAggregate()) {
5368 I->copyInto(*
this, Src);
5370 Src = I->hasLValue() ? I->getKnownLValue().getAddress(*
this)
5371 : I->getKnownRValue().getAggregateAddress();
5381 llvm::TypeSize SrcTypeSize =
5384 if (SrcTypeSize.isScalable()) {
5385 assert(STy->containsHomogeneousScalableVectorTypes() &&
5386 "ABI only supports structure with homogeneous scalable vector "
5388 assert(SrcTypeSize == DstTypeSize &&
5389 "Only allow non-fractional movement of structure with "
5390 "homogeneous scalable vector type");
5391 assert(NumIRArgs == STy->getNumElements());
5393 llvm::Value *StoredStructValue =
5395 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
5396 llvm::Value *Extract =
Builder.CreateExtractValue(
5397 StoredStructValue, i, Src.
getName() +
".extract" + Twine(i));
5398 IRCallArgs[FirstIRArg + i] = Extract;
5401 uint64_t SrcSize = SrcTypeSize.getFixedValue();
5402 uint64_t DstSize = DstTypeSize.getFixedValue();
5408 if (SrcSize < DstSize) {
5417 assert(NumIRArgs == STy->getNumElements());
5418 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
5421 if (ArgHasMaybeUndefAttr)
5422 LI =
Builder.CreateFreeze(LI);
5423 IRCallArgs[FirstIRArg + i] = LI;
5428 assert(NumIRArgs == 1);
5436 auto *ATy = dyn_cast<llvm::ArrayType>(
Load->getType());
5437 if (ATy !=
nullptr && isa<RecordType>(I->Ty.getCanonicalType()))
5441 if (ArgHasMaybeUndefAttr)
5443 IRCallArgs[FirstIRArg] =
Load;
5453 llvm::Value *tempSize =
nullptr;
5456 if (I->isAggregate()) {
5457 addr = I->hasLValue() ? I->getKnownLValue().getAddress(*
this)
5458 : I->getKnownRValue().getAggregateAddress();
5461 RValue RV = I->getKnownRValue();
5473 nullptr, &AllocaAddr);
5481 unsigned IRArgPos = FirstIRArg;
5482 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
5483 llvm::Type *eltType = coercionType->getElementType(i);
5487 if (ArgHasMaybeUndefAttr)
5488 elt =
Builder.CreateFreeze(elt);
5489 IRCallArgs[IRArgPos++] = elt;
5491 assert(IRArgPos == FirstIRArg + NumIRArgs);
5501 unsigned IRArgPos = FirstIRArg;
5502 ExpandTypeToArgs(I->Ty, *I, IRFuncTy, IRCallArgs, IRArgPos);
5503 assert(IRArgPos == FirstIRArg + NumIRArgs);
5509 const CGCallee &ConcreteCallee =
Callee.prepareConcreteCallee(*
this);
5515 assert(IRFunctionArgs.hasInallocaArg());
5516 IRCallArgs[IRFunctionArgs.getInallocaArgNo()] = Arg;
5527 auto simplifyVariadicCallee = [](llvm::FunctionType *CalleeFT,
5528 llvm::Value *Ptr) -> llvm::Function * {
5529 if (!CalleeFT->isVarArg())
5533 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Ptr)) {
5534 if (CE->getOpcode() == llvm::Instruction::BitCast)
5535 Ptr = CE->getOperand(0);
5538 llvm::Function *OrigFn = dyn_cast<llvm::Function>(Ptr);
5542 llvm::FunctionType *OrigFT = OrigFn->getFunctionType();
5546 if (OrigFT->isVarArg() ||
5547 OrigFT->getNumParams() != CalleeFT->getNumParams() ||
5548 OrigFT->getReturnType() != CalleeFT->getReturnType())
5551 for (
unsigned i = 0, e = OrigFT->getNumParams(); i != e; ++i)
5552 if (OrigFT->getParamType(i) != CalleeFT->getParamType(i))
5558 if (llvm::Function *OrigFn = simplifyVariadicCallee(IRFuncTy, CalleePtr)) {
5560 IRFuncTy = OrigFn->getFunctionType();
5575 assert(IRCallArgs.size() == IRFuncTy->getNumParams() || IRFuncTy->isVarArg());
5576 for (
unsigned i = 0; i < IRCallArgs.size(); ++i) {
5578 if (IRFunctionArgs.hasInallocaArg() &&
5579 i == IRFunctionArgs.getInallocaArgNo())
5581 if (i < IRFuncTy->getNumParams())
5582 assert(IRCallArgs[i]->getType() == IRFuncTy->getParamType(i));
5587 for (
unsigned i = 0; i < IRCallArgs.size(); ++i)
5588 LargestVectorWidth = std::max(LargestVectorWidth,
5593 llvm::AttributeList Attrs;
5599 if (
CallingConv == llvm::CallingConv::X86_VectorCall &&
5600 getTarget().getTriple().isWindowsArm64EC()) {
5601 CGM.
Error(Loc,
"__vectorcall calling convention is not currently "
5606 if (FD->hasAttr<StrictFPAttr>())
5608 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::StrictFP);
5613 if (FD->hasAttr<OptimizeNoneAttr>() &&
getLangOpts().FastMath)
5619 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::NoMerge);
5623 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::NoInline);
5628 Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::AlwaysInline);
5637 !(TargetDecl && TargetDecl->
hasAttr<NoInlineAttr>())) {
5639 Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::AlwaysInline);
5644 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::NoInline);
5651 CannotThrow =
false;
5660 CannotThrow = Attrs.hasFnAttr(llvm::Attribute::NoUnwind);
5662 if (
auto *FPtr = dyn_cast<llvm::Function>(CalleePtr))
5663 if (FPtr->hasFnAttribute(llvm::Attribute::NoUnwind))
5671 if (UnusedReturnSizePtr)
5673 UnusedReturnSizePtr);
5675 llvm::BasicBlock *InvokeDest = CannotThrow ? nullptr :
getInvokeDest();
5681 !isa_and_nonnull<FunctionDecl>(TargetDecl))
5685 if (FD->hasAttr<StrictFPAttr>())
5687 Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::StrictFP);
5689 AssumeAlignedAttrEmitter AssumeAlignedAttrEmitter(*
this, TargetDecl);
5690 Attrs = AssumeAlignedAttrEmitter.TryEmitAsCallSiteAttribute(Attrs);
5692 AllocAlignAttrEmitter AllocAlignAttrEmitter(*
this, TargetDecl, CallArgs);
5693 Attrs = AllocAlignAttrEmitter.TryEmitAsCallSiteAttribute(Attrs);
5698 CI =
Builder.CreateCall(IRFuncTy, CalleePtr, IRCallArgs, BundleList);
5701 CI =
Builder.CreateInvoke(IRFuncTy, CalleePtr, Cont, InvokeDest, IRCallArgs,
5705 if (CI->getCalledFunction() && CI->getCalledFunction()->hasName() &&
5706 CI->getCalledFunction()->getName().starts_with(
"_Z4sqrt")) {
5715 if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(
CurFuncDecl)) {
5716 if (
const auto *A = FD->getAttr<CFGuardAttr>()) {
5717 if (A->getGuard() == CFGuardAttr::GuardArg::nocf && !CI->getCalledFunction())
5723 CI->setAttributes(Attrs);
5724 CI->setCallingConv(
static_cast<llvm::CallingConv::ID
>(
CallingConv));
5728 if (!CI->getType()->isVoidTy())
5729 CI->setName(
"call");
5731 if (
getTarget().getTriple().isSPIRVLogical() && CI->isConvergent())
5735 LargestVectorWidth =
5741 if (!CI->getCalledFunction())
5748 AddObjCARCExceptionMetadata(CI);
5751 if (llvm::CallInst *
Call = dyn_cast<llvm::CallInst>(CI)) {
5752 if (TargetDecl && TargetDecl->
hasAttr<NotTailCalledAttr>())
5753 Call->setTailCallKind(llvm::CallInst::TCK_NoTail);
5754 else if (IsMustTail)
5755 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
5760 TargetDecl->
hasAttr<MSAllocatorAttr>())
5764 if (TargetDecl && TargetDecl->
hasAttr<ErrorAttr>()) {
5765 llvm::ConstantInt *
Line =
5767 llvm::ConstantAsMetadata *MD = llvm::ConstantAsMetadata::get(
Line);
5769 CI->setMetadata(
"srcloc", MDT);
5777 if (CI->doesNotReturn()) {
5778 if (UnusedReturnSizePtr)
5782 if (
SanOpts.
has(SanitizerKind::Unreachable)) {
5785 if (
auto *F = CI->getCalledFunction())
5786 F->removeFnAttr(llvm::Attribute::NoReturn);
5787 CI->removeFnAttr(llvm::Attribute::NoReturn);
5792 SanitizerKind::KernelAddress)) {
5793 SanitizerScope SanScope(
this);
5794 llvm::IRBuilder<>::InsertPointGuard IPGuard(
Builder);
5796 auto *FnType = llvm::FunctionType::get(
CGM.
VoidTy,
false);
5797 llvm::FunctionCallee Fn =
5804 Builder.ClearInsertionPoint();
5824 if (CI->getType()->isVoidTy())
5828 Builder.ClearInsertionPoint();
5834 if (swiftErrorTemp.
isValid()) {
5857 bool requiresExtract = isa<llvm::StructType>(CI->getType());
5859 unsigned unpaddedIndex = 0;
5860 for (
unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
5861 llvm::Type *eltType = coercionType->getElementType(i);
5864 llvm::Value *elt = CI;
5865 if (requiresExtract)
5866 elt =
Builder.CreateExtractValue(elt, unpaddedIndex++);
5868 assert(unpaddedIndex == 0);
5877 if (UnusedReturnSizePtr)
5893 llvm::Value *Real =
Builder.CreateExtractValue(CI, 0);
5894 llvm::Value *Imag =
Builder.CreateExtractValue(CI, 1);
5903 DestIsVolatile =
false;
5911 llvm::Value *
V = CI;
5912 if (
V->getType() != RetIRTy)
5917 llvm_unreachable(
"bad evaluation kind");
5923 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(RetIRTy)) {
5924 llvm::Value *
V = CI;
5925 if (
auto *ScalableSrcTy =
5926 dyn_cast<llvm::ScalableVectorType>(
V->getType())) {
5927 if (FixedDstTy->getElementType() == ScalableSrcTy->getElementType()) {
5929 V =
Builder.CreateExtractVector(FixedDstTy,
V, Zero,
"cast.fixed");
5940 DestIsVolatile =
false;
5957 llvm_unreachable(
"Invalid ABI kind for return argument");
5960 llvm_unreachable(
"Unhandled ABIArgInfo::Kind");
5964 if (
Ret.isScalar() && TargetDecl) {
5965 AssumeAlignedAttrEmitter.EmitAsAnAssumption(Loc, RetTy, Ret);
5966 AllocAlignAttrEmitter.EmitAsAnAssumption(Loc, RetTy, Ret);
5971 for (CallLifetimeEnd &LifetimeEnd : CallLifetimeEndAfterCall)
5972 LifetimeEnd.Emit(*
this, {});
static void appendParameterTypes(const CodeGenTypes &CGT, SmallVectorImpl< CanQualType > &prefix, SmallVectorImpl< FunctionProtoType::ExtParameterInfo > ¶mInfos, CanQual< FunctionProtoType > FPT)
Adds the formal parameters in FPT to the given prefix.
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 Address emitAddressAtOffset(CodeGenFunction &CGF, Address addr, const ABIArgInfo &info)
static AggValueSlot createPlaceholderSlot(CodeGenFunction &CGF, QualType Ty)
static void setBitRange(SmallVectorImpl< uint64_t > &Bits, int BitOffset, int BitWidth, int CharWidth)
static SmallVector< CanQualType, 16 > getArgTypesForCall(ASTContext &ctx, const CallArgList &args)
static bool isProvablyNull(llvm::Value *addr)
static void AddAttributesFromFunctionProtoType(ASTContext &Ctx, llvm::AttrBuilder &FuncAttrs, const FunctionProtoType *FPT)
static void eraseUnusedBitCasts(llvm::Instruction *insn)
static bool isObjCMethodWithTypeParams(const ObjCMethodDecl *method)
static void addNoBuiltinAttributes(llvm::AttrBuilder &FuncAttrs, const LangOptions &LangOpts, const NoBuiltinAttr *NBA=nullptr)
static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args, const ObjCIndirectCopyRestoreExpr *CRE)
Emit an argument that's being passed call-by-writeback.
static void overrideFunctionFeaturesWithTargetFeatures(llvm::AttrBuilder &FuncAttr, const llvm::Function &F, const TargetOptions &TargetOpts)
Merges target-features from \TargetOpts and \F, and sets the result in \FuncAttr.
static const CGFunctionInfo & arrangeFreeFunctionLikeCall(CodeGenTypes &CGT, CodeGenModule &CGM, const CallArgList &args, const FunctionType *fnType, unsigned numExtraRequiredArgs, bool chainCall)
Arrange a call as unto a free function, except possibly with an additional number of formal parameter...
static llvm::Value * CreateCoercedLoad(Address Src, llvm::Type *Ty, CodeGenFunction &CGF)
CreateCoercedLoad - Create a load from.
static llvm::SmallVector< FunctionProtoType::ExtParameterInfo, 16 > getExtParameterInfosForCall(const FunctionProtoType *proto, unsigned prefixArgs, unsigned totalArgs)
static CallingConv getCallingConventionForDecl(const ObjCMethodDecl *D, bool IsWindows)
static int getExpansionSize(QualType Ty, const ASTContext &Context)
static CanQual< FunctionProtoType > GetFormalType(const CXXMethodDecl *MD)
Returns the canonical formal type of the given C++ method.
static bool DetermineNoUndef(QualType QTy, CodeGenTypes &Types, const llvm::DataLayout &DL, const ABIArgInfo &AI, bool CheckCoerce=true)
static const Expr * maybeGetUnaryAddrOfOperand(const Expr *E)
static void addDenormalModeAttrs(llvm::DenormalMode FPDenormalMode, llvm::DenormalMode FP32DenormalMode, llvm::AttrBuilder &FuncAttrs)
Add denormal-fp-math and denormal-fp-math-f32 as appropriate for the requested denormal behavior,...
static void emitWritebacks(CodeGenFunction &CGF, const CallArgList &args)
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.
static void CreateCoercedStore(llvm::Value *Src, Address Dst, bool DstIsVolatile, CodeGenFunction &CGF)
CreateCoercedStore - Create a store to.
static SmallVector< CanQualType, 16 > getArgTypesForDeclaration(ASTContext &ctx, const FunctionArgList &args)
static const CGFunctionInfo & arrangeLLVMFunctionInfo(CodeGenTypes &CGT, bool instanceMethod, SmallVectorImpl< CanQualType > &prefix, CanQual< FunctionProtoType > FTP)
Arrange the LLVM function layout for a value of the given function type, on top of any implicit param...
static void addExtParameterInfosForCall(llvm::SmallVectorImpl< FunctionProtoType::ExtParameterInfo > ¶mInfos, const FunctionProtoType *proto, unsigned prefixArgs, unsigned totalArgs)
static bool canApplyNoFPClass(const ABIArgInfo &AI, QualType ParamType, bool IsReturn)
Test if it's legal to apply nofpclass for the given parameter type and it's lowered IR type.
static void getTrivialDefaultFunctionAttributes(StringRef Name, bool HasOptnone, const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts, bool AttrOnCallSite, llvm::AttrBuilder &FuncAttrs)
static llvm::FPClassTest getNoFPClassTestMask(const LangOptions &LangOpts)
Return the nofpclass mask that can be applied to floating-point parameters.
static void forConstantArrayExpansion(CodeGenFunction &CGF, ConstantArrayExpansion *CAE, Address BaseAddr, llvm::function_ref< void(Address)> Fn)
static bool IsArgumentMaybeUndef(const Decl *TargetDecl, unsigned NumRequiredArgs, unsigned ArgNo)
Check if the argument of a function has maybe_undef attribute.
static bool hasInAllocaArgs(CodeGenModule &CGM, CallingConv ExplicitCC, ArrayRef< QualType > ArgTypes)
static std::unique_ptr< TypeExpansion > getTypeExpansion(QualType Ty, const ASTContext &Context)
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 void addMergableDefaultFunctionAttributes(const CodeGenOptions &CodeGenOpts, llvm::AttrBuilder &FuncAttrs)
Add default attributes to a function, which have merge semantics under -mlink-builtin-bitcode and sho...
static llvm::Value * CoerceIntOrPtrToIntOrPtr(llvm::Value *Val, llvm::Type *Ty, CodeGenFunction &CGF)
CoerceIntOrPtrToIntOrPtr - Convert a value Val to the specific Ty where both are either integers or p...
static void AddAttributesFromOMPAssumes(llvm::AttrBuilder &FuncAttrs, const Decl *Callee)
static unsigned getMaxVectorWidth(const llvm::Type *Ty)
CodeGenFunction::ComplexPairTy ComplexPairTy
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
llvm::MachO::Target Target
static QualType getParamType(Sema &SemaRef, ArrayRef< ResultCandidate > Candidates, unsigned N)
Get the type of the Nth parameter from a given set of overload candidates.
static bool isInstanceMethod(const Decl *D)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CanQualType getCanonicalParamType(QualType T) const
Return the canonical parameter type corresponding to the specific potentially non-canonical one.
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CallingConv getDefaultCallingConvention(bool IsVariadic, bool IsCXXMethod, bool IsBuiltin=false) const
Retrieves the default calling convention for the current target.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
TypeInfoChars getTypeInfoInChars(const Type *T) const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const TargetInfo & getTargetInfo() const
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const
Return number of constant array elements.
QualType getIntPtrType() const
Return a type compatible with "intptr_t" (C99 7.18.1.4), as defined by the target.
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.
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
This class is used for builtin types like 'int'.
Represents a base class of a C++ class.
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 LLVM_READONLY
static CanQual< Type > CreateUnsafe(QualType Other)
Builds a canonical type from a QualType.
CanProxy< U > castAs() const
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
CanProxy< U > getAs() const
Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
llvm::DenormalMode FPDenormalMode
The floating-point denormal mode to use.
static StringRef getFramePointerKindName(FramePointerKind Kind)
std::vector< std::string > Reciprocals
llvm::DenormalMode FP32DenormalMode
The floating-point denormal mode to use, for float.
std::string TrapFuncName
If not an empty string, trap intrinsics are lowered to calls to this function instead of to trap inst...
std::vector< std::string > DefaultFunctionAttrs
std::string PreferVectorWidth
The preferred width for auto-vectorization transforms.
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
unsigned getInAllocaFieldIndex() const
bool getIndirectByVal() const
llvm::StructType * getCoerceAndExpandType() const
bool getIndirectRealign() const
void setCoerceToType(llvm::Type *T)
llvm::Type * getUnpaddedCoerceAndExpandType() const
bool getCanBeFlattened() const
unsigned getDirectOffset() const
static bool isPaddingForCoerceAndExpand(llvm::Type *eltType)
bool getInAllocaSRet() const
Return true if this field of an inalloca struct should be returned to implement a struct return calli...
llvm::Type * getPaddingType() const
bool getPaddingInReg() const
unsigned getDirectAlign() const
unsigned getIndirectAddrSpace() const
@ Extend
Extend - Valid only for integer argument types.
@ Ignore
Ignore - Ignore the argument (treat as void).
@ IndirectAliased
IndirectAliased - Similar to Indirect, but the pointer may be to an object that is otherwise referenc...
@ Expand
Expand - Only valid for aggregate argument types.
@ InAlloca
InAlloca - Pass the argument directly using the LLVM inalloca attribute.
@ Indirect
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
@ CoerceAndExpand
CoerceAndExpand - Only valid for aggregate argument types.
@ Direct
Direct - Pass the argument directly using the normal converted LLVM type, or by coercing to another s...
ArrayRef< llvm::Type * > getCoerceAndExpandTypeSequence() const
bool isCoerceAndExpand() const
unsigned getInAllocaIndirect() const
llvm::Type * getCoerceToType() const
bool isIndirectAliased() const
bool isSRetAfterThis() const
bool canHaveCoerceToType() const
CharUnits getIndirectAlign() const
virtual CodeGen::Address EmitMSVAArg(CodeGen::CodeGenFunction &CGF, CodeGen::Address VAListAddr, QualType Ty) const
Emit the target dependent code to load a value of.
virtual CodeGen::Address EmitVAArg(CodeGen::CodeGenFunction &CGF, CodeGen::Address VAListAddr, QualType Ty) const =0
EmitVAArg - Emit the target dependent code to load a value of.
virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const =0
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 withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
llvm::StringRef getName() const
Return the IR name of the pointer value.
llvm::PointerType * getType() const
Return the type 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.
const BlockExpr * BlockExpression
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="")
Address CreateAddrSpaceCast(Address Addr, llvm::Type *Ty, llvm::Type *ElementTy, 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
GlobalDecl getVirtualMethodDecl() const
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
CGFunctionInfo - Class to encapsulate the information about a function definition.
bool usesInAlloca() const
Return true if this function uses inalloca arguments.
FunctionType::ExtInfo getExtInfo() const
bool isInstanceMethod() const
ABIArgInfo & getReturnInfo()
bool isReturnsRetained() const
In ARC, whether this function retains its return value.
void Profile(llvm::FoldingSetNodeID &ID)
const_arg_iterator arg_begin() const
ArrayRef< ExtParameterInfo > getExtParameterInfos() const
CanQualType getReturnType() const
static CGFunctionInfo * create(unsigned llvmCC, bool instanceMethod, bool chainCall, bool delegateCall, const FunctionType::ExtInfo &extInfo, ArrayRef< ExtParameterInfo > paramInfos, CanQualType resultType, ArrayRef< CanQualType > argTypes, RequiredArgs required)
bool isCmseNSCall() const
bool isDelegateCall() const
MutableArrayRef< ArgInfo > arguments()
const_arg_iterator arg_end() const
unsigned getEffectiveCallingConvention() const
getEffectiveCallingConvention - Return the actual calling convention to use, which may depend on the ...
ExtParameterInfo getExtParameterInfo(unsigned argIndex) const
CharUnits getArgStructAlignment() const
unsigned arg_size() const
RequiredArgs getRequiredArgs() const
unsigned getNumRequiredArgs() const
llvm::StructType * getArgStruct() const
Get the struct type used to represent all the arguments in memory.
CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
CallArgList - Type for representing both the value and type of arguments in a call.
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
void addWriteback(LValue srcLV, Address temporary, llvm::Value *toUse)
static ParamValue forIndirect(Address addr)
static ParamValue forDirect(llvm::Value *value)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
EHScopeStack::stable_iterator CurrentCleanupScopeDepth
llvm::Value * EmitLifetimeStart(llvm::TypeSize Size, llvm::Value *Addr)
void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
DeactivateCleanupBlock - Deactivates the given cleanup block.
llvm::Value * EmitNonNullRValueCheck(RValue RV, QualType T)
Create a check that a scalar RValue is non-null.
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
llvm::CallBase * addControlledConvergenceToken(llvm::CallBase *Input)
SanitizerSet SanOpts
Sanitizers enabled for this function.
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 EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr)
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
static bool hasScalarEvaluationKind(QualType T)
bool isCleanupPadScope() const
Returns true while emitting a cleanuppad.
void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)
void EmitKCFIOperandBundle(const CGCallee &Callee, SmallVectorImpl< llvm::OperandBundleDef > &Bundles)
bool shouldUseFusedARCCalls()
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
RValue EmitRValueForField(LValue LV, const FieldDecl *FD, SourceLocation Loc)
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
llvm::Value * EmitARCAutoreleaseReturnValue(llvm::Value *value)
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
bool isSEHTryScope() const
Returns true inside SEH __try blocks.
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
void EmitFunctionEpilog(const CGFunctionInfo &FI, bool EmitRetDbgLoc, SourceLocation EndLoc)
EmitFunctionEpilog - Emit the target specific LLVM code to return the given temporary.
LValue EmitLValueForFieldInitialization(LValue Base, const FieldDecl *Field)
EmitLValueForFieldInitialization - Like EmitLValueForField, except that if the Field is a reference,...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EmitUnreachable(SourceLocation Loc)
Emit a reached-unreachable diagnostic if Loc is valid and runtime checking is enabled.
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...
const CodeGen::CGBlockInfo * BlockInfo
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.
SmallVector< llvm::OperandBundleDef, 1 > getBundlesForFunclet(llvm::Value *Callee)
void callCStructDestructor(LValue Dst)
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
RValue convertTempToRValue(Address addr, QualType type, SourceLocation Loc)
bool InNoMergeAttributedStmt
True if the current statement has nomerge attribute.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, bool IsMustTail, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type,...
llvm::Type * ConvertTypeForMem(QualType T)
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
llvm::BasicBlock * getUnreachableBlock()
bool currentFunctionUsesSEHTry() const
JumpDest ReturnBlock
ReturnBlock - Unified return block.
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
@ ForceLeftToRight
! Language semantics require left-to-right evaluation.
@ ForceRightToLeft
! Language semantics require right-to-left evaluation.
RawAddress CreateMemTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen without...
const TargetInfo & getTarget() const
llvm::Value * EmitCMSEClearRecord(llvm::Value *V, llvm::IntegerType *ITy, QualType RTy)
llvm::Value * getTypeSize(QualType Ty)
Returns calculated size of the specified type.
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 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 EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)
RValue EmitAnyExprToTemp(const Expr *E)
EmitAnyExprToTemp - Similarly to EmitAnyExpr(), however, the result will always be accessible even if...
void EmitReturnValueCheck(llvm::Value *RV)
Emit a test that checks if the return value RV is nonnull.
llvm::BasicBlock * getInvokeDest()
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerMask > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
llvm::Value * EmitARCRetainAutoreleaseReturnValue(llvm::Value *value)
AggValueSlot CreateAggTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateAggTemp - Create a temporary memory object for the given aggregate type.
void EmitDelegateCallArg(CallArgList &args, const VarDecl *param, SourceLocation loc)
EmitDelegateCallArg - We are performing a delegate call; that is, the current function is delegating ...
ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)
EmitLoadOfComplex - Load a complex number from the specified l-value.
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
CGDebugInfo * getDebugInfo()
Address EmitVAListRef(const Expr *E)
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
const TargetCodeGenInfo & getTargetHooks() const
RValue EmitReferenceBindingToExpr(const Expr *E)
Emits a reference binding to the passed in expression.
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
bool InNoInlineAttributedStmt
True if the current statement has noinline attribute.
void EmitAggregateStore(llvm::Value *Val, Address Dest, bool DestIsVolatile)
Build all the stores needed to initialize an aggregate at Dest with the value Val.
void SetSqrtFPAccuracy(llvm::Value *Val)
Set the minimum required accuracy of the given sqrt operation based on CodeGenOpts.
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...
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void checkTargetFeatures(const CallExpr *E, const FunctionDecl *TargetDecl)
Address GetAddressOfBaseClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue, SourceLocation Loc)
GetAddressOfBaseClass - This function will add the necessary delta to the load of 'this' and returns ...
void pushDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind.
bool AutoreleaseResult
In ARC, whether we should autorelease the return value.
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::Type * ConvertType(QualType T)
Address EmitVAArg(VAArgExpr *VE, Address &VAListAddr)
Generate code to get an argument from the passed in pointer and update it accordingly.
void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args)
CodeGenTypes & getTypes() const
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
llvm::CallBase * EmitCallOrInvoke(llvm::FunctionCallee Callee, ArrayRef< llvm::Value * > Args, const Twine &Name="")
bool InAlwaysInlineAttributedStmt
True if the current statement has always_inline attribute.
void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType)
EmitCallArg - Emit a single call argument.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T)
void EmitARCIntrinsicUse(ArrayRef< llvm::Value * > values)
Address EmitMSVAListRef(const Expr *E)
Emit a "reference" to a __builtin_ms_va_list; this is always the value of the expression,...
llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)
static bool hasAggregateEvaluationKind(QualType T)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
const CallExpr * MustTailCall
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
void EmitParmDecl(const VarDecl &D, ParamValue Arg, unsigned ArgNo)
EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl.
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
RValue GetUndefRValue(QualType Ty)
GetUndefRValue - Get an appropriate 'undef' rvalue for the given type.
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()
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
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...
This class organizes the cross-function state that is used while generating LLVM code.
llvm::MDNode * getNoObjCARCExceptionsMetadata()
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
bool ReturnTypeUsesFPRet(QualType ResultType)
Return true iff the given type uses 'fpret' when used as a return type.
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
const LangOptions & getLangOpts() const
CharUnits getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, bool forPointeeType=false)
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
const llvm::DataLayout & getDataLayout() const
ObjCEntrypoints & getObjCEntrypoints() const
void Error(SourceLocation loc, StringRef error)
Emit a general error that something can't be done.
CGCXXABI & getCXXABI() const
bool ReturnTypeUsesFP2Ret(QualType ResultType)
Return true iff the given type uses 'fp2ret' when used as a return type.
bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI)
Return true iff the given type uses an argument slot when 'sret' is used as a return type.
bool ReturnTypeHasInReg(const CGFunctionInfo &FI)
Return true iff the given type has inreg set.
void AdjustMemoryAttribute(StringRef Name, CGCalleeInfo CalleeInfo, llvm::AttributeList &Attrs)
Adjust Memory attribute to ensure that the BE gets the right attribute.
void ConstructAttributeList(StringRef Name, const CGFunctionInfo &Info, CGCalleeInfo CalleeInfo, llvm::AttributeList &Attrs, unsigned &CallingConv, bool AttrOnCallSite, bool IsThunk)
Get the LLVM attributes and calling convention to use for a particular function type.
ASTContext & getContext() const
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)
Return true iff the given type uses 'sret' when used as a return type.
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
void addDefaultFunctionDefinitionAttributes(llvm::AttrBuilder &attrs)
Like the overload taking a Function &, but intended specifically for frontends that want to build on ...
CharUnits getNaturalPointeeTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
llvm::LLVMContext & getLLVMContext()
CharUnits getMinimumObjectSize(QualType Ty)
Returns the minimum object size for an object of the given type.
bool MayDropFunctionReturn(const ASTContext &Context, QualType ReturnType) const
Whether this function's return type has no side effects, and thus may be trivially discarded if it is...
void valueProfile(CGBuilderTy &Builder, uint32_t ValueKind, llvm::Instruction *ValueSite, llvm::Value *ValuePtr)
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
const CGFunctionInfo & arrangeCXXMethodType(const CXXRecordDecl *RD, const FunctionProtoType *FTP, const CXXMethodDecl *MD)
Arrange the argument and result information for a call to an unknown C++ non-static member function o...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
const CGFunctionInfo & arrangeCXXMethodDeclaration(const CXXMethodDecl *MD)
C++ methods have some special rules and also have implicit parameters.
ASTContext & getContext() const
const CGFunctionInfo & arrangeLLVMFunctionInfo(CanQualType returnType, FnInfoOpts opts, ArrayRef< CanQualType > argTypes, FunctionType::ExtInfo info, ArrayRef< FunctionProtoType::ExtParameterInfo > paramInfos, RequiredArgs args)
"Arrange" the LLVM information for a call or type with the given signature.
const ABIInfo & getABIInfo() 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.
unsigned getTargetAddressSpace(QualType T) const
void getExpandedTypes(QualType Ty, SmallVectorImpl< llvm::Type * >::iterator &TI)
getExpandedTypes - Expand the type
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
Objective-C methods are C functions with some implicit parameters.
llvm::LLVMContext & getLLVMContext()
const CGFunctionInfo & arrangeGlobalDeclaration(GlobalDecl GD)
const CGFunctionInfo & arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD)
Arrange a thunk that takes 'this' as the first parameter followed by varargs.
const CGFunctionInfo & arrangeCXXMethodCall(const CallArgList &args, const FunctionProtoType *type, RequiredArgs required, unsigned numPrefixArgs)
Arrange a call to a C++ method, passing the given arguments.
const CGFunctionInfo & arrangeFreeFunctionCall(const CallArgList &Args, const FunctionType *Ty, bool ChainCall)
Figure out the rules for calling a function with the given formal type using the given arguments.
const CGFunctionInfo & arrangeBuiltinFunctionCall(QualType resultType, const CallArgList &args)
const CGFunctionInfo & arrangeFunctionDeclaration(const FunctionDecl *FD)
Free functions are functions that are compatible with an ordinary C function pointer type.
const CGFunctionInfo & arrangeBlockFunctionDeclaration(const FunctionProtoType *type, const FunctionArgList &args)
Block invocation functions are C functions with an implicit parameter.
unsigned ClangCallConvToLLVMCallConv(CallingConv CC)
Convert clang calling convention to LLVM callilng convention.
llvm::Type * GetFunctionTypeForVTable(GlobalDecl GD)
GetFunctionTypeForVTable - Get the LLVM function type for use in a vtable, given a CXXMethodDecl.
const CGFunctionInfo & arrangeCXXConstructorCall(const CallArgList &Args, const CXXConstructorDecl *D, CXXCtorType CtorKind, unsigned ExtraPrefixArgs, unsigned ExtraSuffixArgs, bool PassProtoArgs=true)
Arrange a call to a C++ method, passing the given arguments.
const CGFunctionInfo & arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD, QualType receiverType)
Arrange the argument and result information for the function type through which to perform a send to ...
const CGFunctionInfo & arrangeCXXStructorDeclaration(GlobalDecl GD)
const CGFunctionInfo & arrangeMSCtorClosure(const CXXConstructorDecl *CD, CXXCtorType CT)
const CGFunctionInfo & arrangeCall(const CGFunctionInfo &declFI, const CallArgList &args)
Given a function info for a declaration, return the function info for a call with the given arguments...
const CGFunctionInfo & arrangeNullaryFunction()
A nullary function is a freestanding function of type 'void ()'.
A cleanup scope which generates the cleanup blocks lazily.
EHScopeStack::Cleanup * getCleanup()
Information for lazily generating a cleanup.
virtual bool isRedundantBeforeReturn()
A saved depth on the scope stack.
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
iterator end() const
Returns an iterator pointing to the outermost EH scope.
iterator find(stable_iterator save) const
Turn a stable reference to a scope depth into a unstable pointer to the EH stack.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
bool isVolatileQualified() const
LangAS getAddressSpace() const
CharUnits getAlignment() const
Address getAddress(CodeGenFunction &CGF) const
static LValue MakeAddr(Address Addr, QualType type, ASTContext &Context, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo)
ARCPreciseLifetime_t isARCPreciseLifetime() const
Qualifiers::ObjCLifetime getObjCLifetime() 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.
bool isVolatileQualified() const
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::Type * getElementType() const
Return the type of the values stored in this address.
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 bool doesReturnSlotInterfereWithArgs() const
doesReturnSlotInterfereWithArgs - Return true if the target uses an argument slot for an 'sret' type.
virtual void setCUDAKernelCallingConvention(const FunctionType *&FT) const
Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, LangAS DestAddr, llvm::Type *DestTy, bool IsNonNull=false) const
virtual unsigned getOpenCLKernelCallingConv() const
Get LLVM calling convention for OpenCL kernel.
virtual void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, const FunctionDecl *Callee, const CallArgList &Args) const
Any further codegen related checks that need to be done on a function call in a target specific manne...
virtual bool isNoProtoCallVariadic(const CodeGen::CallArgList &args, const FunctionNoProtoType *fnType) const
Determine whether a call to an unprototyped functions under the given calling convention should use t...
Complex values, per C99 6.2.5p11.
Represents the canonical version of C arrays with a specified constant size.
bool constructsVirtualBase() const
Returns true if the constructed base class is a virtual base class subobject of this declaration's cl...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Decl - This represents one declaration (or definition), e.g.
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
This represents one expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
bool isZeroLengthBitField(const ASTContext &Ctx) const
Is this a zero-length bit-field? Such bit-fields aren't really bit-fields at all and instead act as a...
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
Represents a function declaration or definition.
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Represents a prototype with parameter type info, e.g.
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
unsigned getNumParams() const
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
bool isVariadic() const
Whether this function prototype is variadic.
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
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
QualType getReturnType() const
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
const Decl * getDecl() const
Description of a constructor that was inherited from a base class.
ConstructorUsingShadowDecl * getShadowDecl() const
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
std::vector< std::string > NoBuiltinFuncs
A list of all -fno-builtin-* function names (e.g., memset).
FPExceptionModeKind getDefaultExceptionMode() const
bool isNoBuiltinFunc(StringRef Name) const
Is this a libc/libm function that is no longer recognized as a builtin because a -fno-builtin-* optio...
bool assumeFunctionsAreConvergent() const
Represents a matrix type, as defined in the Matrix Types clang extensions.
Describes a module or submodule.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
ObjCCategoryDecl - Represents a category declaration.
ObjCIndirectCopyRestoreExpr - Represents the passing of a function argument by indirect copy-restore ...
bool shouldCopy() const
shouldCopy - True if we should do the 'copy' part of the copy-restore.
Represents an ObjC class declaration.
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
ArrayRef< ParmVarDecl * > parameters() const
bool isDirectMethod() const
True if the method is tagged as objc_direct.
QualType getReturnType() const
Represents a parameter to a function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
bool isRestrictQualified() const
Determine whether this type is restrict-qualified.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType 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.
bool hasFlexibleArrayMember() const
field_iterator field_end() const
field_range fields() const
bool isParamDestroyedInCallee() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
field_iterator field_begin() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() 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 areArgsDestroyedLeftToRightInCallee() const
Are arguments to a call destroyed left to right in the callee? This is a fundamental language change,...
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool useObjCFPRetForRealType(FloatModeKind T) const
Check whether the given real type should use the "fpret" flavor of Objective-C message passing on thi...
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
bool useObjCFP2RetForComplexLongDouble() const
Check whether _Complex long double should use the "fp2ret" flavor of Objective-C message passing on t...
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.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isBlockPointerType() const
bool isIncompleteArrayType() const
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
QualType getCanonicalTypeInternal() const
bool isMemberPointerType() const
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....
bool isAnyPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isObjCRetainableType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represents a call to the builtin function __builtin_va_arg.
bool isMicrosoftABI() const
Returns whether this is really a Win64 ABI va_arg expression.
const Expr * getSubExpr() const
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.
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...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
void mergeDefaultFunctionDefinitionAttributes(llvm::Function &F, const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts, const TargetOptions &TargetOpts, bool WillInternalize)
Adds attributes to F according to our CodeGenOpts and LangOpts, as though we had emitted it ourselves...
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyRecord - Return true iff a structure contains only empty fields.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
bool This(InterpState &S, CodePtr OpPC)
bool Zero(InterpState &S, CodePtr OpPC)
bool Load(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
@ Vector
'vector' clause, allowed on 'loop', Combined, and 'routine' directives.
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 isUnresolvedExceptionSpec(ExceptionSpecificationType ESpecType)
@ NonNull
Values of this type can never be null.
@ OK_Ordinary
An ordinary object is located at an address in memory.
@ Result
The result type of a method or function.
@ 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.
@ Dtor_Complete
Complete object dtor.
@ CanPassInRegs
The argument of this type can be passed directly in registers.
const FunctionProtoType * T
CallingConv
CallingConv - Specifies the calling convention that a function uses.
__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.
LValue getKnownLValue() const
RValue getKnownRValue() const
void copyInto(CodeGenFunction &CGF, Address A) const
RValue getRValue(CodeGenFunction &CGF) const
llvm::BasicBlock * getBlock() const
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::CallingConv::ID getRuntimeCC() const
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
CharUnits getPointerAlign() const
LangAS getASTAllocaAddressSpace() const
bool isMSVCXXPersonality() const
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.
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.
Iterator for iterating over Stmt * arrays that contain only T *.