;
46using namespaceCodeGen;
52 default:
returnllvm::CallingConv::C;
57 case CC_Win64:
returnllvm::CallingConv::Win64;
59 case CC_AAPCS:
returnllvm::CallingConv::ARM_AAPCS;
60 case CC_AAPCS_VFP:
returnllvm::CallingConv::ARM_AAPCS_VFP;
73 case CC_Swift:
returnllvm::CallingConv::Swift;
75 case CC_M68kRTD:
returnllvm::CallingConv::M68k_RTD;
129 unsignedtotalArgs) {
131assert(paramInfos.size() <= prefixArgs);
132assert(proto->
getNumParams() + prefixArgs <= totalArgs);
134paramInfos.reserve(totalArgs);
137paramInfos.resize(prefixArgs);
141paramInfos.push_back(ParamInfo);
143 if(ParamInfo.hasPassObjectSize())
144paramInfos.emplace_back();
147assert(paramInfos.size() <= totalArgs &&
148 "Did we forget to insert pass_object_size args?");
150paramInfos.resize(totalArgs);
160 if(!FPT->hasExtParameterInfos()) {
161assert(paramInfos.empty() &&
162 "We have paramInfos, but the prototype doesn't?");
163prefix.append(FPT->param_type_begin(), FPT->param_type_end());
167 unsignedPrefixSize = prefix.size();
171prefix.reserve(prefix.size() + FPT->getNumParams());
173 autoExtInfos = FPT->getExtParameterInfos();
174assert(ExtInfos.size() == FPT->getNumParams());
175 for(
unsignedI = 0,
E= FPT->getNumParams(); I !=
E; ++I) {
176prefix.push_back(FPT->getParamType(I));
177 if(ExtInfos[I].hasPassObjectSize())
200FTP->getExtInfo(), paramInfos,
Required);
208return ::arrangeLLVMFunctionInfo(*
this,
false, argTypes,
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>())
287return ::arrangeLLVMFunctionInfo(
288*
this,
true, argTypes,
295 if(FD->
hasAttr<CUDAGlobalAttr>()) {
308assert(!isa<CXXConstructorDecl>(MD) &&
"wrong method for constructors!");
309assert(!isa<CXXDestructorDecl>(MD) &&
"wrong method for destructors!");
331!
Target.getCXXABI().hasConstructorVariants();
336 auto*MD = cast<CXXMethodDecl>(GD.
getDecl());
344 boolPassParams =
true;
346 if(
auto*CD = dyn_cast<CXXConstructorDecl>(MD)) {
349 if(
autoInherited = CD->getInheritedConstructor())
361 if(!paramInfos.empty()) {
364paramInfos.insert(paramInfos.begin() + 1, AddedArgs.
Prefix,
367paramInfos.append(AddedArgs.
Suffix,
372(PassParams && MD->isVariadic() ?
RequiredArgs(argTypes.size())
381argTypes, extInfo, paramInfos, required);
387 for(
auto&arg : args)
395 for(
auto&arg : args)
402 unsignedprefixArgs,
unsignedtotalArgs) {
422 unsignedExtraPrefixArgs,
423 unsignedExtraSuffixArgs,
424 boolPassProtoArgs) {
427 for(
const auto&Arg : args)
431 unsignedTotalPrefixArgs = 1 + ExtraPrefixArgs;
436FPT, TotalPrefixArgs + ExtraSuffixArgs)
449 if(PassProtoArgs && FPT->hasExtParameterInfos()) {
456ArgTypes, Info, ParamInfos,
Required);
464 if(MD->isImplicitObjectMemberFunction())
469assert(isa<FunctionType>(FTy));
476{}, noProto->getExtInfo(), {},
511I->hasAttr<NoEscapeAttr>());
512extParamInfos.push_back(extParamInfo);
519 if(
getContext().getLangOpts().ObjCAutoRefCount &&
520MD->
hasAttr<NSReturnsRetainedAttr>())
546 if(isa<CXXConstructorDecl>(GD.
getDecl()) ||
547isa<CXXDestructorDecl>(GD.
getDecl()))
560assert(MD->
isVirtual() &&
"only methods have thunks");
577ArgTys.push_back(*FTP->param_type_begin());
579ArgTys.push_back(Context.
IntTy);
594 unsignednumExtraRequiredArgs,
596assert(args.size() >= numExtraRequiredArgs);
606 if(proto->isVariadic())
609 if(proto->hasExtParameterInfos())
619cast<FunctionNoProtoType>(fnType))) {
625 for(
const auto&arg : args)
630paramInfos, required);
642chainCall ? 1 : 0, chainCall);
671 for(
const auto&Arg : args)
704 unsignednumPrefixArgs) {
705assert(numPrefixArgs + 1 <= args.size() &&
706 "Emitting a call with less args than the required prefix?");
718paramInfos, required);
730assert(signature.
arg_size() <= args.size());
731 if(signature.
arg_size() == args.size())
736 if(!sigParamInfos.empty()) {
737paramInfos.append(sigParamInfos.begin(), sigParamInfos.end());
738paramInfos.resize(args.size());
770assert(llvm::all_of(argTypes,
774llvm::FoldingSetNodeID ID;
779 boolisDelegateCall =
782info, paramInfos, required, resultType, argTypes);
784 void*insertPos =
nullptr;
785 CGFunctionInfo*FI = FunctionInfos.FindNodeOrInsertPos(ID, insertPos);
793info, paramInfos, resultType, argTypes, required);
794FunctionInfos.InsertNode(FI, insertPos);
796 boolinserted = FunctionsBeingProcessed.insert(FI).second;
798assert(inserted &&
"Recursively being processed?");
801 if(CC == llvm::CallingConv::SPIR_KERNEL) {
819 if(I.info.canHaveCoerceToType() && I.info.getCoerceToType() ==
nullptr)
822 boolerased = FunctionsBeingProcessed.erase(FI); (void)erased;
823assert(erased &&
"Not in set?");
829 boolchainCall,
booldelegateCall,
835assert(paramInfos.empty() || paramInfos.size() == argTypes.size());
840 operator new(totalSizeToAlloc<ArgInfo, ExtParameterInfo>(
841argTypes.size() + 1, paramInfos.size()));
844FI->CallingConvention = llvmCC;
845FI->EffectiveCallingConvention = llvmCC;
846FI->ASTCallingConvention = info.
getCC();
847FI->InstanceMethod = instanceMethod;
848FI->ChainCall = chainCall;
849FI->DelegateCall = delegateCall;
855FI->Required = required;
858FI->ArgStruct =
nullptr;
859FI->ArgStructAlign = 0;
860FI->NumArgs = argTypes.size();
861FI->HasExtParameterInfos = !paramInfos.empty();
862FI->getArgsBuffer()[0].
type= resultType;
863FI->MaxVectorWidth = 0;
864 for(
unsignedi = 0, e = argTypes.size(); i != e; ++i)
865FI->getArgsBuffer()[i + 1].
type= argTypes[i];
866 for(
unsignedi = 0, e = paramInfos.size(); i != e; ++i)
867FI->getExtParameterInfosBuffer()[i] = paramInfos[i];
877structTypeExpansion {
878 enumTypeExpansionKind {
890 constTypeExpansionKind
Kind;
892TypeExpansion(TypeExpansionKind K) :
Kind(K) {}
893 virtual~TypeExpansion() {}
896structConstantArrayExpansion : TypeExpansion {
900ConstantArrayExpansion(
QualTypeEltTy, uint64_t NumElts)
901: TypeExpansion(TEK_ConstantArray), EltTy(EltTy), NumElts(NumElts) {}
902 static boolclassof(
constTypeExpansion *TE) {
903 returnTE->Kind == TEK_ConstantArray;
907structRecordExpansion : TypeExpansion {
914: TypeExpansion(TEK_Record), Bases(
std::move(Bases)),
915Fields(
std::move(Fields)) {}
916 static boolclassof(
constTypeExpansion *TE) {
917 returnTE->Kind == TEK_Record;
921structComplexExpansion : TypeExpansion {
925 static boolclassof(
constTypeExpansion *TE) {
930structNoExpansion : TypeExpansion {
931NoExpansion() : TypeExpansion(TEK_None) {}
932 static boolclassof(
constTypeExpansion *TE) {
933 returnTE->Kind == TEK_None;
938staticstd::unique_ptr<TypeExpansion>
941 returnstd::make_unique<ConstantArrayExpansion>(AT->getElementType(),
949 "Cannot expand structure with flexible array.");
956 for(
const auto*FD : RD->
fields()) {
957 if(FD->isZeroLengthBitField())
959assert(!FD->isBitField() &&
960 "Cannot expand structure with bit-field members.");
962 if(UnionSize < FieldSize) {
963UnionSize = FieldSize;
968Fields.push_back(LargestFD);
970 if(
const auto*CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
971assert(!CXXRD->isDynamicClass() &&
972 "cannot expand vtable pointers in dynamic classes");
973llvm::append_range(Bases, llvm::make_pointer_range(CXXRD->bases()));
976 for(
const auto*FD : RD->
fields()) {
977 if(FD->isZeroLengthBitField())
979assert(!FD->isBitField() &&
980 "Cannot expand structure with bit-field members.");
981Fields.push_back(FD);
984 returnstd::make_unique<RecordExpansion>(std::move(Bases),
988 returnstd::make_unique<ComplexExpansion>(CT->getElementType());
990 returnstd::make_unique<NoExpansion>();
995 if(
autoCAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
998 if(
autoRExp = dyn_cast<RecordExpansion>(Exp.get())) {
1000 for(
autoBS : RExp->Bases)
1002 for(
autoFD : RExp->Fields)
1006 if(isa<ComplexExpansion>(Exp.get()))
1008assert(isa<NoExpansion>(Exp.get()));
1016 if(
autoCAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1017 for(
inti = 0, n = CAExp->NumElts; i < n; i++) {
1020}
else if(
autoRExp = dyn_cast<RecordExpansion>(Exp.get())) {
1021 for(
autoBS : RExp->Bases)
1023 for(
autoFD : RExp->Fields)
1025}
else if(
autoCExp = dyn_cast<ComplexExpansion>(Exp.get())) {
1030assert(isa<NoExpansion>(Exp.get()));
1036ConstantArrayExpansion *CAE,
1038llvm::function_ref<
void(
Address)> Fn) {
1039 for(
inti = 0, n = CAE->NumElts; i < n; i++) {
1046llvm::Function::arg_iterator &AI) {
1048 "Unexpected non-simple lvalue during struct expansion.");
1051 if(
autoCAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1054LValue LV = MakeAddrLValue(EltAddr, CAExp->EltTy);
1055ExpandTypeFromArgs(CAExp->EltTy, LV, AI);
1057}
else if(
autoRExp = dyn_cast<RecordExpansion>(Exp.get())) {
1067ExpandTypeFromArgs(BS->
getType(), SubLV, AI);
1069 for(
autoFD : RExp->Fields) {
1072ExpandTypeFromArgs(FD->getType(), SubLV, AI);
1074}
else if(isa<ComplexExpansion>(Exp.get())) {
1075 autorealValue = &*AI++;
1076 autoimagValue = &*AI++;
1081assert(isa<NoExpansion>(Exp.get()));
1082llvm::Value *Arg = &*AI++;
1089 if(Arg->getType()->isPointerTy()) {
1098voidCodeGenFunction::ExpandTypeToArgs(
1102 if(
autoCAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1106*
this, CAExp, Addr, [&](
AddressEltAddr) {
1110ExpandTypeToArgs(CAExp->EltTy, EltArg, IRFuncTy, IRCallArgs,
1113}
else if(
autoRExp = dyn_cast<RecordExpansion>(Exp.get())) {
1124ExpandTypeToArgs(BS->
getType(), BaseArg, IRFuncTy, IRCallArgs,
1129 for(
autoFD : RExp->Fields) {
1132ExpandTypeToArgs(FD->getType(), FldArg, IRFuncTy, IRCallArgs,
1135}
else if(isa<ComplexExpansion>(Exp.get())) {
1137IRCallArgs[IRCallArgPos++] = CV.first;
1138IRCallArgs[IRCallArgPos++] = CV.second;
1140assert(isa<NoExpansion>(Exp.get()));
1142assert(RV.isScalar() &&
1143 "Unexpected non-scalar rvalue during struct expansion.");
1146llvm::Value *
V= RV.getScalarVal();
1147 if(IRCallArgPos < IRFuncTy->getNumParams() &&
1148 V->getType() != IRFuncTy->getParamType(IRCallArgPos))
1149 V=
Builder.CreateBitCast(
V, IRFuncTy->getParamType(IRCallArgPos));
1151IRCallArgs[IRCallArgPos++] =
V;
1159 constTwine &Name =
"tmp") {
1173llvm::StructType *SrcSTy,
1176 if(SrcSTy->getNumElements() == 0)
returnSrcPtr;
1184uint64_t FirstEltSize =
1186 if(FirstEltSize < DstSize &&
1195 if(llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy))
1211 if(Val->getType() == Ty)
1214 if(isa<llvm::PointerType>(Val->getType())) {
1216 if(isa<llvm::PointerType>(Ty))
1217 returnCGF.
Builder.CreateBitCast(Val, Ty,
"coerce.val");
1220Val = CGF.
Builder.CreatePtrToInt(Val, CGF.
IntPtrTy,
"coerce.val.pi");
1223llvm::Type *DestIntTy = Ty;
1224 if(isa<llvm::PointerType>(DestIntTy))
1227 if(Val->getType() != DestIntTy) {
1229 if(DL.isBigEndian()) {
1232uint64_t SrcSize = DL.getTypeSizeInBits(Val->getType());
1233uint64_t DstSize = DL.getTypeSizeInBits(DestIntTy);
1235 if(SrcSize > DstSize) {
1236Val = CGF.
Builder.CreateLShr(Val, SrcSize - DstSize,
"coerce.highbits");
1237Val = CGF.
Builder.CreateTrunc(Val, DestIntTy,
"coerce.val.ii");
1239Val = CGF.
Builder.CreateZExt(Val, DestIntTy,
"coerce.val.ii");
1240Val = CGF.
Builder.CreateShl(Val, DstSize - SrcSize,
"coerce.highbits");
1244Val = CGF.
Builder.CreateIntCast(Val, DestIntTy,
false,
"coerce.val.ii");
1248 if(isa<llvm::PointerType>(Ty))
1249Val = CGF.
Builder.CreateIntToPtr(Val, Ty,
"coerce.val.ip");
1272 if(llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy)) {
1274DstSize.getFixedValue(), CGF);
1278llvm::TypeSize SrcSize = CGF.
CGM.
getDataLayout().getTypeAllocSize(SrcTy);
1282 if((isa<llvm::IntegerType>(Ty) || isa<llvm::PointerType>(Ty)) &&
1283(isa<llvm::IntegerType>(SrcTy) || isa<llvm::PointerType>(SrcTy))) {
1289 if(!SrcSize.isScalable() && !DstSize.isScalable() &&
1290SrcSize.getFixedValue() >= DstSize.getFixedValue()) {
1304 if(
auto*ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(Ty)) {
1305 if(
auto*FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
1308 if(ScalableDstTy->getElementType()->isIntegerTy(1) &&
1309ScalableDstTy->getElementCount().isKnownMultipleOf(8) &&
1310FixedSrcTy->getElementType()->isIntegerTy(8)) {
1311ScalableDstTy = llvm::ScalableVectorType::get(
1312FixedSrcTy->getElementType(),
1313ScalableDstTy->getElementCount().getKnownMinValue() / 8);
1315 if(ScalableDstTy->getElementType() == FixedSrcTy->getElementType()) {
1317 auto*PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
1318 auto*Zero = llvm::Constant::getNullValue(CGF.
CGM.
Int64Ty);
1320ScalableDstTy, PoisonVec, Load, Zero,
"cast.scalable");
1321 if(ScalableDstTy != Ty)
1334llvm::ConstantInt::get(CGF.
IntPtrTy, SrcSize.getKnownMinValue()));
1339llvm::TypeSize DstSize,
1340 boolDstIsVolatile) {
1344llvm::Type *SrcTy = Src->getType();
1351 if(llvm::StructType *DstSTy =
1353assert(!SrcSize.isScalable());
1355SrcSize.getFixedValue(), *
this);
1359 if(SrcSize.isScalable() || SrcSize <= DstSize) {
1360 if(SrcTy->isIntegerTy() && Dst.
getElementType()->isPointerTy() &&
1365}
else if(llvm::StructType *STy =
1366dyn_cast<llvm::StructType>(Src->getType())) {
1369 for(
unsignedi = 0, e = STy->getNumElements(); i != e; ++i) {
1371llvm::Value *Elt =
Builder.CreateExtractValue(Src, i);
1377}
else if(SrcTy->isIntegerTy()) {
1379llvm::Type *DstIntTy =
Builder.getIntNTy(DstSize.getFixedValue() * 8);
1413staticstd::pair<llvm::Value *, bool>
1415llvm::ScalableVectorType *FromTy, llvm::Value *
V,
1416StringRef Name =
"") {
1419 if(FromTy->getElementType()->isIntegerTy(1) &&
1420FromTy->getElementCount().isKnownMultipleOf(8) &&
1421ToTy->getElementType() == CGF.
Builder.getInt8Ty()) {
1422FromTy = llvm::ScalableVectorType::get(
1423ToTy->getElementType(),
1424FromTy->getElementCount().getKnownMinValue() / 8);
1425 V= CGF.
Builder.CreateBitCast(
V, FromTy);
1427 if(FromTy->getElementType() == ToTy->getElementType()) {
1428llvm::Value *Zero = llvm::Constant::getNullValue(CGF.
CGM.
Int64Ty);
1430 V->setName(Name +
".coerce");
1431 V= CGF.
Builder.CreateExtractVector(ToTy,
V, Zero,
"cast.fixed");
1432 return{
V,
true};
1434 return{
V,
false};
1441classClangToLLVMArgMapping {
1442 static const unsignedInvalidIndex = ~0
U;
1443 unsignedInallocaArgNo;
1445 unsignedTotalIRArgs;
1449 unsignedPaddingArgIndex;
1452 unsignedFirstArgIndex;
1453 unsignedNumberOfArgs;
1456: PaddingArgIndex(InvalidIndex), FirstArgIndex(InvalidIndex),
1464 boolOnlyRequiredArgs =
false)
1465: InallocaArgNo(InvalidIndex), SRetArgNo(InvalidIndex), TotalIRArgs(0),
1466ArgInfo(OnlyRequiredArgs ? FI.getNumRequiredArgs() : FI.arg_size()) {
1467construct(Context, FI, OnlyRequiredArgs);
1470 boolhasInallocaArg()
const{
returnInallocaArgNo != InvalidIndex; }
1471 unsignedgetInallocaArgNo()
const{
1472assert(hasInallocaArg());
1473 returnInallocaArgNo;
1476 boolhasSRetArg()
const{
returnSRetArgNo != InvalidIndex; }
1477 unsignedgetSRetArgNo()
const{
1478assert(hasSRetArg());
1482 unsignedtotalIRArgs()
const{
returnTotalIRArgs; }
1484 boolhasPaddingArg(
unsignedArgNo)
const{
1485assert(ArgNo < ArgInfo.size());
1486 returnArgInfo[ArgNo].PaddingArgIndex != InvalidIndex;
1488 unsignedgetPaddingArgNo(
unsignedArgNo)
const{
1489assert(hasPaddingArg(ArgNo));
1490 returnArgInfo[ArgNo].PaddingArgIndex;
1495std::pair<unsigned, unsigned> getIRArgs(
unsignedArgNo)
const{
1496assert(ArgNo < ArgInfo.size());
1497 returnstd::make_pair(ArgInfo[ArgNo].FirstArgIndex,
1498ArgInfo[ArgNo].NumberOfArgs);
1503 boolOnlyRequiredArgs);
1506voidClangToLLVMArgMapping::construct(
const ASTContext&Context,
1508 boolOnlyRequiredArgs) {
1509 unsignedIRArgNo = 0;
1510 boolSwapThisWithSRet =
false;
1515SRetArgNo = SwapThisWithSRet ? 1 : IRArgNo++;
1526 auto&IRArgs = ArgInfo[ArgNo];
1529IRArgs.PaddingArgIndex = IRArgNo++;
1535llvm::StructType *STy = dyn_cast<llvm::StructType>(AI.
getCoerceToType());
1537IRArgs.NumberOfArgs = STy->getNumElements();
1539IRArgs.NumberOfArgs = 1;
1545IRArgs.NumberOfArgs = 1;
1550IRArgs.NumberOfArgs = 0;
1560 if(IRArgs.NumberOfArgs > 0) {
1561IRArgs.FirstArgIndex = IRArgNo;
1562IRArgNo += IRArgs.NumberOfArgs;
1567 if(IRArgNo == 1 && SwapThisWithSRet)
1570assert(ArgNo == ArgInfo.size());
1573InallocaArgNo = IRArgNo++;
1575TotalIRArgs = IRArgNo;
1583 returnRI.
isIndirect() || (RI.isInAlloca() && RI.getInAllocaSRet());
1598 switch(BT->getKind()) {
1601 caseBuiltinType::Float:
1603 caseBuiltinType::Double:
1605 caseBuiltinType::LongDouble:
1616 if(BT->getKind() == BuiltinType::LongDouble)
1629llvm::FunctionType *
1632 boolInserted = FunctionsBeingProcessed.insert(&FI).second;
1634assert(Inserted &&
"Recursively being processed?");
1636llvm::Type *resultType =
nullptr;
1641llvm_unreachable(
"Invalid ABI kind for return argument");
1653resultType = llvm::PointerType::get(
getLLVMContext(), addressSpace);
1669ClangToLLVMArgMapping IRFunctionArgs(
getContext(), FI,
true);
1673 if(IRFunctionArgs.hasSRetArg()) {
1676ArgTypes[IRFunctionArgs.getSRetArgNo()] =
1681 if(IRFunctionArgs.hasInallocaArg())
1682ArgTypes[IRFunctionArgs.getInallocaArgNo()] =
1689 for(; it != ie; ++it, ++ArgNo) {
1693 if(IRFunctionArgs.hasPaddingArg(ArgNo))
1694ArgTypes[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
1697 unsignedFirstIRArg, NumIRArgs;
1698std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
1700 switch(ArgInfo.
getKind()) {
1703assert(NumIRArgs == 0);
1707assert(NumIRArgs == 1);
1709ArgTypes[FirstIRArg] = llvm::PointerType::get(
1713assert(NumIRArgs == 1);
1714ArgTypes[FirstIRArg] = llvm::PointerType::get(
1722llvm::StructType *st = dyn_cast<llvm::StructType>(argType);
1724assert(NumIRArgs == st->getNumElements());
1725 for(
unsignedi = 0, e = st->getNumElements(); i != e; ++i)
1726ArgTypes[FirstIRArg + i] = st->getElementType(i);
1728assert(NumIRArgs == 1);
1729ArgTypes[FirstIRArg] = argType;
1735 autoArgTypesIter = ArgTypes.begin() + FirstIRArg;
1737*ArgTypesIter++ = EltTy;
1739assert(ArgTypesIter == ArgTypes.begin() + FirstIRArg + NumIRArgs);
1744 autoArgTypesIter = ArgTypes.begin() + FirstIRArg;
1746assert(ArgTypesIter == ArgTypes.begin() + FirstIRArg + NumIRArgs);
1751 boolErased = FunctionsBeingProcessed.erase(&FI); (void)Erased;
1752assert(Erased &&
"Not in set?");
1754 returnllvm::FunctionType::get(resultType, ArgTypes, FI.
isVariadic());
1768llvm::AttrBuilder &FuncAttrs,
1775FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
1779FuncAttrs.addAttribute(
"aarch64_pstate_sm_enabled");
1781FuncAttrs.addAttribute(
"aarch64_pstate_sm_compatible");
1783FuncAttrs.addAttribute(
"aarch64_za_state_agnostic");
1787FuncAttrs.addAttribute(
"aarch64_preserves_za");
1789FuncAttrs.addAttribute(
"aarch64_in_za");
1791FuncAttrs.addAttribute(
"aarch64_out_za");
1793FuncAttrs.addAttribute(
"aarch64_inout_za");
1797FuncAttrs.addAttribute(
"aarch64_preserves_zt0");
1799FuncAttrs.addAttribute(
"aarch64_in_zt0");
1801FuncAttrs.addAttribute(
"aarch64_out_zt0");
1803FuncAttrs.addAttribute(
"aarch64_inout_zt0");
1807 const Decl*Callee) {
1813 for(
constOMPAssumeAttr *AA : Callee->specific_attrs<OMPAssumeAttr>())
1814AA->getAssumption().split(Attrs,
",");
1817FuncAttrs.addAttribute(llvm::AssumptionAttrKey,
1818llvm::join(Attrs.begin(), Attrs.end(),
","));
1827 if(
const auto*ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl()))
1828 returnClassDecl->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);
1869llvm::DenormalMode FP32DenormalMode,
1870llvm::AttrBuilder &FuncAttrs) {
1871 if(FPDenormalMode != llvm::DenormalMode::getDefault())
1872FuncAttrs.addAttribute(
"denormal-fp-math", FPDenormalMode.str());
1874 if(FP32DenormalMode != FPDenormalMode && FP32DenormalMode.isValid())
1875FuncAttrs.addAttribute(
"denormal-fp-math-f32", FP32DenormalMode.str());
1883llvm::AttrBuilder &FuncAttrs) {
1889StringRef Name,
boolHasOptnone,
const CodeGenOptions&CodeGenOpts,
1891llvm::AttrBuilder &FuncAttrs) {
1894 if(CodeGenOpts.OptimizeSize)
1895FuncAttrs.addAttribute(llvm::Attribute::OptimizeForSize);
1896 if(CodeGenOpts.OptimizeSize == 2)
1897FuncAttrs.addAttribute(llvm::Attribute::MinSize);
1900 if(CodeGenOpts.DisableRedZone)
1901FuncAttrs.addAttribute(llvm::Attribute::NoRedZone);
1902 if(CodeGenOpts.IndirectTlsSegRefs)
1903FuncAttrs.addAttribute(
"indirect-tls-seg-refs");
1904 if(CodeGenOpts.NoImplicitFloat)
1905FuncAttrs.addAttribute(llvm::Attribute::NoImplicitFloat);
1907 if(AttrOnCallSite) {
1911 if(!CodeGenOpts.SimplifyLibCalls || LangOpts.
isNoBuiltinFunc(Name))
1912FuncAttrs.addAttribute(llvm::Attribute::NoBuiltin);
1914FuncAttrs.addAttribute(
"trap-func-name", CodeGenOpts.
TrapFuncName);
1916 switch(CodeGenOpts.getFramePointer()) {
1923FuncAttrs.addAttribute(
"frame-pointer",
1925CodeGenOpts.getFramePointer()));
1928 if(CodeGenOpts.LessPreciseFPMAD)
1929FuncAttrs.addAttribute(
"less-precise-fpmad",
"true");
1931 if(CodeGenOpts.NullPointerIsValid)
1932FuncAttrs.addAttribute(llvm::Attribute::NullPointerIsValid);
1935FuncAttrs.addAttribute(
"no-trapping-math",
"true");
1939 if(LangOpts.NoHonorInfs)
1940FuncAttrs.addAttribute(
"no-infs-fp-math",
"true");
1941 if(LangOpts.NoHonorNaNs)
1942FuncAttrs.addAttribute(
"no-nans-fp-math",
"true");
1943 if(LangOpts.ApproxFunc)
1944FuncAttrs.addAttribute(
"approx-func-fp-math",
"true");
1945 if(LangOpts.AllowFPReassoc && LangOpts.AllowRecip &&
1946LangOpts.NoSignedZero && LangOpts.ApproxFunc &&
1947(LangOpts.getDefaultFPContractMode() ==
1949LangOpts.getDefaultFPContractMode() ==
1951FuncAttrs.addAttribute(
"unsafe-fp-math",
"true");
1952 if(CodeGenOpts.SoftFloat)
1953FuncAttrs.addAttribute(
"use-soft-float",
"true");
1954FuncAttrs.addAttribute(
"stack-protector-buffer-size",
1955llvm::utostr(CodeGenOpts.SSPBufferSize));
1956 if(LangOpts.NoSignedZero)
1957FuncAttrs.addAttribute(
"no-signed-zeros-fp-math",
"true");
1960 conststd::vector<std::string> &Recips = CodeGenOpts.
Reciprocals;
1961 if(!Recips.empty())
1962FuncAttrs.addAttribute(
"reciprocal-estimates",
1963llvm::join(Recips,
","));
1967FuncAttrs.addAttribute(
"prefer-vector-width",
1970 if(CodeGenOpts.StackRealignment)
1971FuncAttrs.addAttribute(
"stackrealign");
1972 if(CodeGenOpts.Backchain)
1973FuncAttrs.addAttribute(
"backchain");
1974 if(CodeGenOpts.EnableSegmentedStacks)
1975FuncAttrs.addAttribute(
"split-stack");
1977 if(CodeGenOpts.SpeculativeLoadHardening)
1978FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
1981 switch(CodeGenOpts.getZeroCallUsedRegs()) {
1982 casellvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Skip:
1983FuncAttrs.removeAttribute(
"zero-call-used-regs");
1985 casellvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPRArg:
1986FuncAttrs.addAttribute(
"zero-call-used-regs",
"used-gpr-arg");
1988 casellvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPR:
1989FuncAttrs.addAttribute(
"zero-call-used-regs",
"used-gpr");
1991 casellvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedArg:
1992FuncAttrs.addAttribute(
"zero-call-used-regs",
"used-arg");
1994 casellvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Used:
1995FuncAttrs.addAttribute(
"zero-call-used-regs",
"used");
1997 casellvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPRArg:
1998FuncAttrs.addAttribute(
"zero-call-used-regs",
"all-gpr-arg");
2000 casellvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPR:
2001FuncAttrs.addAttribute(
"zero-call-used-regs",
"all-gpr");
2003 casellvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllArg:
2004FuncAttrs.addAttribute(
"zero-call-used-regs",
"all-arg");
2006 casellvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::All:
2007FuncAttrs.addAttribute(
"zero-call-used-regs",
"all");
2018FuncAttrs.addAttribute(llvm::Attribute::Convergent);
2023 if((LangOpts.CUDA && LangOpts.CUDAIsDevice) || LangOpts.OpenCL ||
2024LangOpts.SYCLIsDevice) {
2025FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2028 if(CodeGenOpts.SaveRegParams && !AttrOnCallSite)
2029FuncAttrs.addAttribute(
"save-reg-params");
2032StringRef Var,
Value;
2033std::tie(Var,
Value) =
Attr.split(
'=');
2034FuncAttrs.addAttribute(Var,
Value);
2048 constllvm::Function &F,
2050 autoFFeatures = F.getFnAttribute(
"target-features");
2052llvm::StringSet<> MergedNames;
2054MergedFeatures.reserve(TargetOpts.
Features.size());
2056 autoAddUnmergedFeatures = [&](
auto&&FeatureRange) {
2057 for(StringRef Feature : FeatureRange) {
2058 if(Feature.empty())
2060assert(Feature[0] ==
'+'|| Feature[0] ==
'-');
2061StringRef Name = Feature.drop_front(1);
2062 boolMerged = !MergedNames.insert(Name).second;
2064MergedFeatures.push_back(Feature);
2068 if(FFeatures.isValid())
2069AddUnmergedFeatures(llvm::split(FFeatures.getValueAsString(),
','));
2070AddUnmergedFeatures(TargetOpts.
Features);
2072 if(!MergedFeatures.empty()) {
2073llvm::sort(MergedFeatures);
2074FuncAttr.addAttribute(
"target-features", llvm::join(MergedFeatures,
","));
2081 boolWillInternalize) {
2083llvm::AttrBuilder FuncAttrs(F.getContext());
2086 if(!TargetOpts.
CPU.empty())
2087FuncAttrs.addAttribute(
"target-cpu", TargetOpts.
CPU);
2088 if(!TargetOpts.
TuneCPU.empty())
2089FuncAttrs.addAttribute(
"tune-cpu", TargetOpts.
TuneCPU);
2092CodeGenOpts, LangOpts,
2095 if(!WillInternalize && F.isInterposable()) {
2100F.addFnAttrs(FuncAttrs);
2104llvm::AttributeMask AttrsToRemove;
2106llvm::DenormalMode DenormModeToMerge = F.getDenormalModeRaw();
2107llvm::DenormalMode DenormModeToMergeF32 = F.getDenormalModeF32Raw();
2108llvm::DenormalMode Merged =
2112 if(DenormModeToMergeF32.isValid()) {
2117 if(Merged == llvm::DenormalMode::getDefault()) {
2118AttrsToRemove.addAttribute(
"denormal-fp-math");
2119}
else if(Merged != DenormModeToMerge) {
2121FuncAttrs.addAttribute(
"denormal-fp-math",
2125 if(MergedF32 == llvm::DenormalMode::getDefault()) {
2126AttrsToRemove.addAttribute(
"denormal-fp-math-f32");
2127}
else if(MergedF32 != DenormModeToMergeF32) {
2129FuncAttrs.addAttribute(
"denormal-fp-math-f32",
2133F.removeFnAttrs(AttrsToRemove);
2138F.addFnAttrs(FuncAttrs);
2141voidCodeGenModule::getTrivialDefaultFunctionAttributes(
2142StringRef Name,
boolHasOptnone,
boolAttrOnCallSite,
2143llvm::AttrBuilder &FuncAttrs) {
2144::getTrivialDefaultFunctionAttributes(Name, HasOptnone,
getCodeGenOpts(),
2149voidCodeGenModule::getDefaultFunctionAttributes(StringRef Name,
2151 boolAttrOnCallSite,
2152llvm::AttrBuilder &FuncAttrs) {
2153getTrivialDefaultFunctionAttributes(Name, HasOptnone, AttrOnCallSite,
2157 if(!AttrOnCallSite)
2162llvm::AttrBuilder &attrs) {
2163getDefaultFunctionAttributes(
"",
false,
2165GetCPUAndFeaturesAttributes(
GlobalDecl(), attrs);
2170 constNoBuiltinAttr *NBA =
nullptr) {
2171 autoAddNoBuiltinAttr = [&FuncAttrs](StringRef BuiltinName) {
2173AttributeName +=
"no-builtin-";
2174AttributeName += BuiltinName;
2175FuncAttrs.addAttribute(AttributeName);
2179 if(LangOpts.NoBuiltin) {
2181FuncAttrs.addAttribute(
"no-builtins");
2195 if(llvm::is_contained(NBA->builtinNames(),
"*")) {
2196FuncAttrs.addAttribute(
"no-builtins");
2201llvm::for_each(NBA->builtinNames(), AddNoBuiltinAttr);
2205 constllvm::DataLayout &DL,
const ABIArgInfo&AI,
2206 boolCheckCoerce =
true) {
2207llvm::Type *Ty = Types.ConvertTypeForMem(QTy);
2213 if(!DL.typeSizeEqualsStoreSize(Ty))
2220 if(llvm::TypeSize::isKnownGT(DL.getTypeSizeInBits(CoerceTy),
2221DL.getTypeSizeInBits(Ty)))
2245 if(
const MatrixType*Matrix = dyn_cast<MatrixType>(QTy))
2247 if(
const ArrayType*Array = dyn_cast<ArrayType>(QTy))
2256 unsignedNumRequiredArgs,
unsignedArgNo) {
2257 const auto*FD = dyn_cast_or_null<FunctionDecl>(TargetDecl);
2262 if(ArgNo >= NumRequiredArgs)
2266 if(ArgNo < FD->getNumParams()) {
2267 const ParmVarDecl*Param = FD->getParamDecl(ArgNo);
2268 if(Param && Param->
hasAttr<MaybeUndefAttr>())
2285 if(llvm::AttributeFuncs::isNoFPClassCompatibleType(IRTy))
2288 if(llvm::StructType *ST = dyn_cast<llvm::StructType>(IRTy)) {
2290llvm::all_of(ST->elements(), [](llvm::Type *Ty) {
2291return llvm::AttributeFuncs::isNoFPClassCompatibleType(Ty);
2300llvm::FPClassTest Mask = llvm::fcNone;
2301 if(LangOpts.NoHonorInfs)
2302Mask |= llvm::fcInf;
2303 if(LangOpts.NoHonorNaNs)
2304Mask |= llvm::fcNan;
2310llvm::AttributeList &Attrs) {
2311 if(Attrs.getMemoryEffects().getModRef() == llvm::ModRefInfo::NoModRef) {
2312Attrs = Attrs.removeFnAttribute(
getLLVMContext(), llvm::Attribute::Memory);
2313llvm::Attribute MemoryAttr = llvm::Attribute::getWithMemoryEffects(
2339llvm::AttributeList &AttrList,
2341 boolAttrOnCallSite,
boolIsThunk) {
2349FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2351FuncAttrs.addAttribute(
"cmse_nonsecure_call");
2363 boolHasOptnone =
false;
2365 constNoBuiltinAttr *NBA =
nullptr;
2369 autoAddPotentialArgAccess = [&]() {
2370llvm::Attribute A = FuncAttrs.getAttribute(llvm::Attribute::Memory);
2372FuncAttrs.addMemoryAttr(A.getMemoryEffects() |
2373llvm::MemoryEffects::argMemOnly());
2380 if(TargetDecl->
hasAttr<ReturnsTwiceAttr>())
2381FuncAttrs.addAttribute(llvm::Attribute::ReturnsTwice);
2382 if(TargetDecl->
hasAttr<NoThrowAttr>())
2383FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2384 if(TargetDecl->
hasAttr<NoReturnAttr>())
2385FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2386 if(TargetDecl->
hasAttr<ColdAttr>())
2387FuncAttrs.addAttribute(llvm::Attribute::Cold);
2388 if(TargetDecl->
hasAttr<HotAttr>())
2389FuncAttrs.addAttribute(llvm::Attribute::Hot);
2390 if(TargetDecl->
hasAttr<NoDuplicateAttr>())
2391FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate);
2392 if(TargetDecl->
hasAttr<ConvergentAttr>())
2393FuncAttrs.addAttribute(llvm::Attribute::Convergent);
2395 if(
const FunctionDecl*Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
2398 if(AttrOnCallSite && Fn->isReplaceableGlobalAllocationFunction()) {
2400 autoKind = Fn->getDeclName().getCXXOverloadedOperator();
2402(Kind == OO_New || Kind == OO_Array_New))
2403RetAttrs.addAttribute(llvm::Attribute::NoAlias);
2406 const boolIsVirtualCall = MD && MD->
isVirtual();
2409 if(!(AttrOnCallSite && IsVirtualCall)) {
2410 if(Fn->isNoReturn())
2411FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2412NBA = Fn->getAttr<NoBuiltinAttr>();
2416 if(isa<FunctionDecl>(TargetDecl) || isa<VarDecl>(TargetDecl)) {
2419 if(AttrOnCallSite && TargetDecl->
hasAttr<NoMergeAttr>())
2420FuncAttrs.addAttribute(llvm::Attribute::NoMerge);
2424 if(TargetDecl->
hasAttr<ConstAttr>()) {
2425FuncAttrs.addMemoryAttr(llvm::MemoryEffects::none());
2426FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2429FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
2430}
else if(TargetDecl->
hasAttr<PureAttr>()) {
2431FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
2432FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2434FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
2435}
else if(TargetDecl->
hasAttr<NoAliasAttr>()) {
2436FuncAttrs.addMemoryAttr(llvm::MemoryEffects::inaccessibleOrArgMemOnly());
2437FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2439 if(TargetDecl->
hasAttr<RestrictAttr>())
2440RetAttrs.addAttribute(llvm::Attribute::NoAlias);
2441 if(TargetDecl->
hasAttr<ReturnsNonNullAttr>() &&
2442!CodeGenOpts.NullPointerIsValid)
2443RetAttrs.addAttribute(llvm::Attribute::NonNull);
2444 if(TargetDecl->
hasAttr<AnyX86NoCallerSavedRegistersAttr>())
2445FuncAttrs.addAttribute(
"no_caller_saved_registers");
2446 if(TargetDecl->
hasAttr<AnyX86NoCfCheckAttr>())
2447FuncAttrs.addAttribute(llvm::Attribute::NoCfCheck);
2448 if(TargetDecl->
hasAttr<LeafAttr>())
2449FuncAttrs.addAttribute(llvm::Attribute::NoCallback);
2450 if(TargetDecl->
hasAttr<BPFFastCallAttr>())
2451FuncAttrs.addAttribute(
"bpf_fastcall");
2453HasOptnone = TargetDecl->
hasAttr<OptimizeNoneAttr>();
2454 if(
auto*AllocSize = TargetDecl->
getAttr<AllocSizeAttr>()) {
2455std::optional<unsigned> NumElemsParam;
2456 if(AllocSize->getNumElemsParam().isValid())
2457NumElemsParam = AllocSize->getNumElemsParam().getLLVMIndex();
2458FuncAttrs.addAllocSizeAttr(AllocSize->getElemSizeParam().getLLVMIndex(),
2462 if(TargetDecl->
hasAttr<OpenCLKernelAttr>()) {
2465FuncAttrs.addAttribute(
"uniform-work-group-size",
"true");
2472FuncAttrs.addAttribute(
2473 "uniform-work-group-size",
2474llvm::toStringRef(
getLangOpts().OffloadUniformBlock));
2478 if(TargetDecl->
hasAttr<CUDAGlobalAttr>() &&
2480FuncAttrs.addAttribute(
"uniform-work-group-size",
"true");
2482 if(TargetDecl->
hasAttr<ArmLocallyStreamingAttr>())
2483FuncAttrs.addAttribute(
"aarch64_pstate_sm_body");
2495getDefaultFunctionAttributes(Name, HasOptnone, AttrOnCallSite, FuncAttrs);
2500 if(TargetDecl->
hasAttr<NoSpeculativeLoadHardeningAttr>())
2501FuncAttrs.removeAttribute(llvm::Attribute::SpeculativeLoadHardening);
2502 if(TargetDecl->
hasAttr<SpeculativeLoadHardeningAttr>())
2503FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
2504 if(TargetDecl->
hasAttr<NoSplitStackAttr>())
2505FuncAttrs.removeAttribute(
"split-stack");
2506 if(TargetDecl->
hasAttr<ZeroCallUsedRegsAttr>()) {
2509TargetDecl->
getAttr<ZeroCallUsedRegsAttr>()->getZeroCallUsedRegs();
2510FuncAttrs.removeAttribute(
"zero-call-used-regs");
2511FuncAttrs.addAttribute(
2512 "zero-call-used-regs",
2513ZeroCallUsedRegsAttr::ConvertZeroCallUsedRegsKindToStr(Kind));
2520 if(CodeGenOpts.NoPLT) {
2521 if(
auto*Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
2522 if(!Fn->isDefined() && !AttrOnCallSite) {
2523FuncAttrs.addAttribute(llvm::Attribute::NonLazyBind);
2528 if(TargetDecl->
hasAttr<NoConvergentAttr>())
2529FuncAttrs.removeAttribute(llvm::Attribute::Convergent);
2534 if(TargetDecl && CodeGenOpts.UniqueInternalLinkageNames) {
2535 if(
const auto*FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
2536 if(!FD->isExternallyVisible())
2537FuncAttrs.addAttribute(
"sample-profile-suffix-elision-policy",
2544 if(!AttrOnCallSite) {
2545 if(TargetDecl && TargetDecl->
hasAttr<CmseNSEntryAttr>())
2546FuncAttrs.addAttribute(
"cmse_nonsecure_entry");
2549 autoshouldDisableTailCalls = [&] {
2551 if(CodeGenOpts.DisableTailCalls)
2557 if(TargetDecl->
hasAttr<DisableTailCallsAttr>() ||
2558TargetDecl->
hasAttr<AnyX86InterruptAttr>())
2561 if(CodeGenOpts.NoEscapingBlockTailCalls) {
2562 if(
const auto*BD = dyn_cast<BlockDecl>(TargetDecl))
2563 if(!BD->doesNotEscape())
2569 if(shouldDisableTailCalls())
2570FuncAttrs.addAttribute(
"disable-tail-calls",
"true");
2574GetCPUAndFeaturesAttributes(CalleeInfo.
getCalleeDecl(), FuncAttrs);
2578ClangToLLVMArgMapping IRFunctionArgs(
getContext(), FI);
2585 if(CodeGenOpts.EnableNoundefAttrs &&
2589RetAttrs.addAttribute(llvm::Attribute::NoUndef);
2595RetAttrs.addAttribute(llvm::Attribute::SExt);
2597RetAttrs.addAttribute(llvm::Attribute::ZExt);
2599RetAttrs.addAttribute(llvm::Attribute::NoExt);
2603RetAttrs.addAttribute(llvm::Attribute::InReg);
2615AddPotentialArgAccess();
2624llvm_unreachable(
"Invalid ABI kind for return argument");
2632RetAttrs.addDereferenceableAttr(
2634 if(
getTypes().getTargetAddressSpace(PTy) == 0 &&
2635!CodeGenOpts.NullPointerIsValid)
2636RetAttrs.addAttribute(llvm::Attribute::NonNull);
2638llvm::Align Alignment =
2640RetAttrs.addAlignmentAttr(Alignment);
2645 boolhasUsedSRet =
false;
2649 if(IRFunctionArgs.hasSRetArg()) {
2651SRETAttrs.addStructRetAttr(
getTypes().ConvertTypeForMem(RetTy));
2652SRETAttrs.addAttribute(llvm::Attribute::Writable);
2653SRETAttrs.addAttribute(llvm::Attribute::DeadOnUnwind);
2654hasUsedSRet =
true;
2656SRETAttrs.addAttribute(llvm::Attribute::InReg);
2658ArgAttrs[IRFunctionArgs.getSRetArgNo()] =
2663 if(IRFunctionArgs.hasInallocaArg()) {
2666ArgAttrs[IRFunctionArgs.getInallocaArgNo()] =
2674!FI.
arg_begin()->
type->isVoidPointerType() && !IsThunk) {
2675 autoIRArgs = IRFunctionArgs.getIRArgs(0);
2677assert(IRArgs.second == 1 &&
"Expected only a single `this` pointer.");
2684 if(!CodeGenOpts.NullPointerIsValid &&
2686Attrs.addAttribute(llvm::Attribute::NonNull);
2693Attrs.addDereferenceableOrNullAttr(
2699llvm::Align Alignment =
2703Attrs.addAlignmentAttr(Alignment);
2705ArgAttrs[IRArgs.first] = llvm::AttributeSet::get(
getLLVMContext(), Attrs);
2711I !=
E; ++I, ++ArgNo) {
2717 if(IRFunctionArgs.hasPaddingArg(ArgNo)) {
2719ArgAttrs[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
2720llvm::AttributeSet::get(
2722llvm::AttrBuilder(
getLLVMContext()).addAttribute(llvm::Attribute::InReg));
2727 if(CodeGenOpts.EnableNoundefAttrs &&
2729Attrs.addAttribute(llvm::Attribute::NoUndef);
2738Attrs.addAttribute(llvm::Attribute::SExt);
2740Attrs.addAttribute(llvm::Attribute::ZExt);
2742Attrs.addAttribute(llvm::Attribute::NoExt);
2746Attrs.addAttribute(llvm::Attribute::Nest);
2748Attrs.addAttribute(llvm::Attribute::InReg);
2749Attrs.addStackAlignmentAttr(llvm::MaybeAlign(AI.
getDirectAlign()));
2756Attrs.addAttribute(llvm::Attribute::InReg);
2759Attrs.addByValAttr(
getTypes().ConvertTypeForMem(ParamType));
2762 if(CodeGenOpts.PassByValueIsNoAlias &&
Decl&&
2763 Decl->getArgPassingRestrictions() ==
2767Attrs.addAttribute(llvm::Attribute::NoAlias);
2784assert(!Align.
isZero());
2792AddPotentialArgAccess();
2797Attrs.addByRefAttr(
getTypes().ConvertTypeForMem(ParamType));
2808AddPotentialArgAccess();
2815Attrs.addDereferenceableAttr(
2817 if(
getTypes().getTargetAddressSpace(PTy) == 0 &&
2818!CodeGenOpts.NullPointerIsValid)
2819Attrs.addAttribute(llvm::Attribute::NonNull);
2821llvm::Align Alignment =
2823Attrs.addAlignmentAttr(Alignment);
2831 if(TargetDecl && TargetDecl->
hasAttr<OpenCLKernelAttr>() &&
2835llvm::Align Alignment =
2837Attrs.addAlignmentAttr(Alignment);
2844Attrs.addAttribute(llvm::Attribute::NoAlias);
2853Attrs.addStructRetAttr(
getTypes().ConvertTypeForMem(ParamType));
2854hasUsedSRet =
true;
2858Attrs.addAttribute(llvm::Attribute::NoAlias);
2862 if(!PTy->isIncompleteType() && PTy->isConstantSizeType()) {
2864Attrs.addDereferenceableAttr(info.Width.getQuantity());
2865Attrs.addAlignmentAttr(info.Align.getAsAlign());
2871Attrs.addAttribute(llvm::Attribute::SwiftError);
2875Attrs.addAttribute(llvm::Attribute::SwiftSelf);
2879Attrs.addAttribute(llvm::Attribute::SwiftAsync);
2884Attrs.addCapturesAttr(llvm::CaptureInfo::none());
2886 if(Attrs.hasAttributes()) {
2887 unsignedFirstIRArg, NumIRArgs;
2888std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
2889 for(
unsignedi = 0; i < NumIRArgs; i++)
2890ArgAttrs[FirstIRArg + i] = ArgAttrs[FirstIRArg + i].addAttributes(
2896AttrList = llvm::AttributeList::get(
2898llvm::AttributeSet::get(
getLLVMContext(), RetAttrs), ArgAttrs);
2905llvm::Value *value) {
2906llvm::Type *varType = CGF.
ConvertType(var->getType());
2910 if(value->getType() == varType)
returnvalue;
2912assert((varType->isIntegerTy() || varType->isFloatingPointTy())
2913&&
"unexpected promotion type");
2915 if(isa<llvm::IntegerType>(varType))
2916 returnCGF.
Builder.CreateTrunc(value, varType,
"arg.unpromote");
2918 returnCGF.
Builder.CreateFPCast(value, varType,
"arg.unpromote");
2924 QualTypeArgType,
unsignedArgNo) {
2936 if(
autoParmNNAttr = PVD->
getAttr<NonNullAttr>())
2942 for(
const auto*NNAttr : FD->
specific_attrs<NonNullAttr>()) {
2943 if(NNAttr->isNonNull(ArgNo))
2973 if(FD->hasImplicitReturnZero()) {
2974 QualTypeRetTy = FD->getReturnType().getUnqualifiedType();
2976llvm::Constant*
Zero= llvm::Constant::getNullValue(LLVMTy);
2984ClangToLLVMArgMapping IRFunctionArgs(
CGM.
getContext(), FI);
2985assert(
Fn->arg_size() == IRFunctionArgs.totalIRArgs());
2990 if(IRFunctionArgs.hasInallocaArg())
2991ArgStruct =
Address(
Fn->getArg(IRFunctionArgs.getInallocaArgNo()),
2995 if(IRFunctionArgs.hasSRetArg()) {
2996 autoAI =
Fn->getArg(IRFunctionArgs.getSRetArgNo());
2997AI->setName(
"agg.result");
2998AI->addAttr(llvm::Attribute::NoAlias);
3005ArgVals.reserve(Args.size());
3011assert(FI.
arg_size() == Args.size() &&
3012 "Mismatch between function signature & arguments.");
3015 for(FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
3016i != e; ++i, ++info_it, ++ArgNo) {
3021isa<ParmVarDecl>(Arg) && cast<ParmVarDecl>(Arg)->isKNRPromoted();
3029 unsignedFirstIRArg, NumIRArgs;
3030std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
3034assert(NumIRArgs == 0);
3047assert(NumIRArgs == 1);
3070llvm::ConstantInt::get(
IntPtrTy,
Size.getQuantity()));
3071ParamAddr = AlignedTemp;
3088 autoAI =
Fn->getArg(FirstIRArg);
3096assert(NumIRArgs == 1);
3098 if(
const ParmVarDecl*PVD = dyn_cast<ParmVarDecl>(Arg)) {
3101PVD->getFunctionScopeIndex()) &&
3103AI->addAttr(llvm::Attribute::NonNull);
3105 QualTypeOTy = PVD->getOriginalType();
3106 if(
const auto*ArrTy =
3113 QualTypeETy = ArrTy->getElementType();
3114llvm::Align Alignment =
3116AI->addAttrs(llvm::AttrBuilder(
getLLVMContext()).addAlignmentAttr(Alignment));
3117 uint64_tArrSize = ArrTy->getZExtSize();
3121Attrs.addDereferenceableAttr(
3122 getContext().getTypeSizeInChars(ETy).getQuantity() *
3124AI->addAttrs(Attrs);
3125}
else if(
getContext().getTargetInfo().getNullPointerValue(
3128AI->addAttr(llvm::Attribute::NonNull);
3131}
else if(
const auto*ArrTy =
3137 QualTypeETy = ArrTy->getElementType();
3138llvm::Align Alignment =
3140AI->addAttrs(llvm::AttrBuilder(
getLLVMContext()).addAlignmentAttr(Alignment));
3141 if(!
getTypes().getTargetAddressSpace(ETy) &&
3143AI->addAttr(llvm::Attribute::NonNull);
3148 const auto*AVAttr = PVD->getAttr<AlignValueAttr>();
3151AVAttr = TOTy->getDecl()->getAttr<AlignValueAttr>();
3152 if(AVAttr && !
SanOpts.
has(SanitizerKind::Alignment)) {
3156llvm::ConstantInt *AlignmentCI =
3157cast<llvm::ConstantInt>(
EmitScalarExpr(AVAttr->getAlignment()));
3159AlignmentCI->getLimitedValue(llvm::Value::MaximumAlignment);
3160 if(AI->getParamAlign().valueOrOne() < AlignmentInt) {
3161AI->removeAttr(llvm::Attribute::AttrKind::Alignment);
3162AI->addAttrs(llvm::AttrBuilder(
getLLVMContext()).addAlignmentAttr(
3163llvm::Align(AlignmentInt)));
3170AI->addAttr(llvm::Attribute::NoAlias);
3178assert(NumIRArgs == 1);
3182llvm::Value *
V= AI;
3190 V, pointeeTy,
getContext().getTypeAlignInChars(pointeeTy));
3213 if(
V->getType() != LTy)
3224 if(
auto*VecTyTo = dyn_cast<llvm::FixedVectorType>(
ConvertType(Ty))) {
3225llvm::Value *ArgVal =
Fn->getArg(FirstIRArg);
3226 if(
auto*VecTyFrom =
3227dyn_cast<llvm::ScalableVectorType>(ArgVal->getType())) {
3229*
this, VecTyTo, VecTyFrom, ArgVal, Arg->
getName());
3231assert(NumIRArgs == 1);
3238llvm::StructType *STy =
3249STy->getNumElements() > 1) {
3251llvm::TypeSize PtrElementSize =
3253 if(StructSize.isScalable()) {
3254assert(STy->containsHomogeneousScalableVectorTypes() &&
3255 "ABI only supports structure with homogeneous scalable vector " 3257assert(StructSize == PtrElementSize &&
3258 "Only allow non-fractional movement of structure with" 3259 "homogeneous scalable vector type");
3260assert(STy->getNumElements() == NumIRArgs);
3262llvm::Value *LoadedStructValue = llvm::PoisonValue::get(STy);
3263 for(
unsignedi = 0, e = STy->getNumElements(); i != e; ++i) {
3264 auto*AI =
Fn->getArg(FirstIRArg + i);
3265AI->setName(Arg->
getName() +
".coerce"+ Twine(i));
3267 Builder.CreateInsertValue(LoadedStructValue, AI, i);
3272 uint64_tSrcSize = StructSize.getFixedValue();
3273 uint64_tDstSize = PtrElementSize.getFixedValue();
3276 if(SrcSize <= DstSize) {
3283assert(STy->getNumElements() == NumIRArgs);
3284 for(
unsignedi = 0, e = STy->getNumElements(); i != e; ++i) {
3285 autoAI =
Fn->getArg(FirstIRArg + i);
3286AI->setName(Arg->
getName() +
".coerce"+ Twine(i));
3291 if(SrcSize > DstSize) {
3297assert(NumIRArgs == 1);
3298 autoAI =
Fn->getArg(FirstIRArg);
3299AI->setName(Arg->
getName() +
".coerce");
3302llvm::TypeSize::getFixed(
3303 getContext().getTypeSizeInChars(Ty).getQuantity() -
3328 auto*unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
3332 unsignedargIndex = FirstIRArg;
3333 unsignedunpaddedIndex = 0;
3334 for(
unsignedi = 0, e = coercionType->getNumElements(); i != e; ++i) {
3335llvm::Type *eltType = coercionType->getElementType(i);
3340llvm::Value *elt =
Fn->getArg(argIndex++);
3342 autoparamType = unpaddedStruct
3343? unpaddedStruct->getElementType(unpaddedIndex++)
3344: unpaddedCoercionType;
3346 if(
auto*VecTyTo = dyn_cast<llvm::FixedVectorType>(eltType)) {
3347 if(
auto*VecTyFrom = dyn_cast<llvm::ScalableVectorType>(paramType)) {
3350*
this, VecTyTo, VecTyFrom, elt, elt->getName());
3351assert(Extracted &&
"Unexpected scalable to fixed vector coercion");
3356assert(argIndex == FirstIRArg + NumIRArgs);
3368 autoFnArgIter =
Fn->arg_begin() + FirstIRArg;
3369ExpandTypeFromArgs(Ty, LV, FnArgIter);
3370assert(FnArgIter ==
Fn->arg_begin() + FirstIRArg + NumIRArgs);
3371 for(
unsignedi = 0, e = NumIRArgs; i != e; ++i) {
3372 autoAI =
Fn->getArg(FirstIRArg + i);
3373AI->setName(Arg->
getName() +
"."+ Twine(i));
3379assert(NumIRArgs == 0);
3391 if(
getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) {
3392 for(
intI = Args.size() - 1; I >= 0; --I)
3395 for(
unsignedI = 0,
E= Args.size(); I !=
E; ++I)
3401 while(insn->use_empty()) {
3402llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(insn);
3403 if(!bitcast)
return;
3406insn = cast<llvm::Instruction>(bitcast->getOperand(0));
3407bitcast->eraseFromParent();
3413llvm::Value *result) {
3415llvm::BasicBlock *BB = CGF.
Builder.GetInsertBlock();
3416 if(BB->empty())
return nullptr;
3417 if(&BB->back() != result)
return nullptr;
3419llvm::Type *resultType = result->getType();
3422llvm::Instruction *generator = cast<llvm::Instruction>(result);
3428 while(llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(generator)) {
3431generator = cast<llvm::Instruction>(bitcast->getOperand(0));
3434 if(generator->getNextNode() != bitcast)
3437InstsToKill.push_back(bitcast);
3444llvm::CallInst *call = dyn_cast<llvm::CallInst>(generator);
3445 if(!call)
return nullptr;
3447 booldoRetainAutorelease;
3450doRetainAutorelease =
true;
3451}
else if(call->getCalledOperand() ==
3453doRetainAutorelease =
false;
3461llvm::Instruction *prev = call->getPrevNode();
3463 if(isa<llvm::BitCastInst>(prev)) {
3464prev = prev->getPrevNode();
3467assert(isa<llvm::CallInst>(prev));
3468assert(cast<llvm::CallInst>(prev)->getCalledOperand() ==
3470InstsToKill.push_back(prev);
3476result = call->getArgOperand(0);
3477InstsToKill.push_back(call);
3481 while(llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(result)) {
3482 if(!bitcast->hasOneUse())
break;
3483InstsToKill.push_back(bitcast);
3484result = bitcast->getOperand(0);
3488 for(
auto*I : InstsToKill)
3489I->eraseFromParent();
3492 if(doRetainAutorelease)
3496 returnCGF.
Builder.CreateBitCast(result, resultType);
3501llvm::Value *result) {
3504dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurCodeDecl);
3505 if(!method)
return nullptr;
3511llvm::CallInst *retainCall = dyn_cast<llvm::CallInst>(result);
3512 if(!retainCall || retainCall->getCalledOperand() !=
3517llvm::Value *retainedValue = retainCall->getArgOperand(0);
3518llvm::LoadInst *load =
3519dyn_cast<llvm::LoadInst>(retainedValue->stripPointerCasts());
3520 if(!load || load->isAtomic() || load->isVolatile() ||
3527llvm::Type *resultType = result->getType();
3529assert(retainCall->use_empty());
3530retainCall->eraseFromParent();
3533 returnCGF.
Builder.CreateBitCast(load, resultType);
3540llvm::Value *result) {
3563 autoGetStoreIfValid = [&CGF,
3564ReturnValuePtr](llvm::User *
U) -> llvm::StoreInst * {
3565 auto*SI = dyn_cast<llvm::StoreInst>(
U);
3566 if(!SI || SI->getPointerOperand() != ReturnValuePtr ||
3572assert(!SI->isAtomic() &&
3580 if(!ReturnValuePtr->hasOneUse()) {
3581llvm::BasicBlock *IP = CGF.
Builder.GetInsertBlock();
3582 if(IP->empty())
return nullptr;
3586 constllvm::Instruction *LoadIntoFakeUse =
nullptr;
3587 for(llvm::Instruction &I : make_range(IP->rbegin(), IP->rend())) {
3591 if(LoadIntoFakeUse == &I)
3593 if(isa<llvm::BitCastInst>(&I))
3595 if(
auto*II = dyn_cast<llvm::IntrinsicInst>(&I)) {
3596 if(II->getIntrinsicID() == llvm::Intrinsic::lifetime_end)
3599 if(II->getIntrinsicID() == llvm::Intrinsic::fake_use) {
3600LoadIntoFakeUse = dyn_cast<llvm::Instruction>(II->getArgOperand(0));
3604 returnGetStoreIfValid(&I);
3609llvm::StoreInst *store = GetStoreIfValid(ReturnValuePtr->user_back());
3610 if(!store)
return nullptr;
3614llvm::BasicBlock *StoreBB = store->getParent();
3615llvm::BasicBlock *IP = CGF.
Builder.GetInsertBlock();
3617 while(IP != StoreBB) {
3618 if(!SeenBBs.insert(IP).second || !(IP = IP->getSinglePredecessor()))
3634 intBitWidth,
intCharWidth) {
3635assert(CharWidth <= 64);
3636assert(
static_cast<unsigned>(BitWidth) <= Bits.size() * CharWidth);
3639 if(BitOffset >= CharWidth) {
3640Pos += BitOffset / CharWidth;
3641BitOffset = BitOffset % CharWidth;
3644 constuint64_t
Used= (uint64_t(1) << CharWidth) - 1;
3645 if(BitOffset + BitWidth >= CharWidth) {
3646Bits[Pos++] |= (
Used<< BitOffset) &
Used;
3647BitWidth -= CharWidth - BitOffset;
3651 while(BitWidth >= CharWidth) {
3652Bits[Pos++] =
Used;
3653BitWidth -= CharWidth;
3657Bits[Pos++] |= (
Used>> (CharWidth - BitWidth)) << BitOffset;
3665 intStorageSize,
intBitOffset,
intBitWidth,
3666 intCharWidth,
boolBigEndian) {
3669 setBitRange(TmpBits, BitOffset, BitWidth, CharWidth);
3672std::reverse(TmpBits.begin(), TmpBits.end());
3674 for(uint64_t
V: TmpBits)
3675Bits[StorageOffset++] |=
V;
3706BFI.
Size, CharWidth,
3728 autoSrc = TmpBits.begin();
3729 autoDst = Bits.begin() + Offset + I * Size;
3730 for(
intJ = 0; J < Size; ++J)
3750std::fill_n(Bits.begin() + Offset, Size,
3755 intPos,
intSize,
intCharWidth,
3760 for(
auto P= Bits.begin() + Pos,
E= Bits.begin() + Pos + Size;
P!=
E;
3762Mask = (Mask << CharWidth) | *
P;
3764 auto P= Bits.begin() + Pos + Size, End = Bits.begin() + Pos;
3766Mask = (Mask << CharWidth) | *--
P;
3775llvm::IntegerType *ITy,
3777assert(Src->getType() == ITy);
3778assert(ITy->getScalarSizeInBits() <= 64);
3781 int Size= DataLayout.getTypeStoreSize(ITy);
3789 return Builder.CreateAnd(Src, Mask,
"cmse.clear");
3795llvm::ArrayType *ATy,
3798 int Size= DataLayout.getTypeStoreSize(ATy);
3805ATy->getArrayElementType()->getScalarSizeInBits() / CharWidth;
3807llvm::Value *R = llvm::PoisonValue::get(ATy);
3808 for(
intI = 0, N = ATy->getArrayNumElements(); I != N; ++I) {
3810DataLayout.isBigEndian());
3811MaskIndex += CharsPerElt;
3812llvm::Value *T0 =
Builder.CreateExtractValue(Src, I);
3813llvm::Value *T1 =
Builder.CreateAnd(T0, Mask,
"cmse.clear");
3814R =
Builder.CreateInsertValue(R, T1, I);
3841llvm::DebugLoc RetDbgLoc;
3842llvm::Value *RV =
nullptr;
3852llvm::Function::arg_iterator EI =
CurFn->arg_end();
3854llvm::Value *ArgStruct = &*EI;
3858cast<llvm::GetElementPtrInst>(SRet)->getResultElementType();
3864 autoAI =
CurFn->arg_begin();
3904 if(llvm::StoreInst *SI =
3910RetDbgLoc = SI->getDebugLoc();
3912RV = SI->getValueOperand();
3913SI->eraseFromParent();
3936 if(
auto*FD = dyn_cast<FunctionDecl>(
CurCodeDecl))
3937RT = FD->getReturnType();
3938 else if(
auto*MD = dyn_cast<ObjCMethodDecl>(
CurCodeDecl))
3939RT = MD->getReturnType();
3943llvm_unreachable(
"Unexpected function/method type");
3960 auto*unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
3965 unsignedunpaddedIndex = 0;
3966 for(
unsignedi = 0, e = coercionType->getNumElements(); i != e; ++i) {
3967 autocoercedEltType = coercionType->getElementType(i);
3974unpaddedStruct ? unpaddedStruct->getElementType(unpaddedIndex++)
3975: unpaddedCoercionType,
3977results.push_back(elt);
3981 if(results.size() == 1) {
3989RV = llvm::PoisonValue::get(returnType);
3990 for(
unsignedi = 0, e = results.size(); i != e; ++i) {
3991RV =
Builder.CreateInsertValue(RV, results[i], i);
3998llvm_unreachable(
"Invalid ABI kind for return argument");
4001llvm::Instruction *
Ret;
4007 auto*ITy = dyn_cast<llvm::IntegerType>(RV->getType());
4018 Ret->setDebugLoc(std::move(RetDbgLoc));
4031ReturnsNonNullAttr *RetNNAttr =
nullptr;
4032 if(
SanOpts.
has(SanitizerKind::ReturnsNonnullAttribute))
4035 if(!RetNNAttr && !requiresReturnValueNullabilityCheck())
4043assert(!requiresReturnValueNullabilityCheck() &&
4044 "Cannot check nullability and the nonnull attribute");
4045AttrLoc = RetNNAttr->getLocation();
4046CheckKind = SanitizerKind::SO_ReturnsNonnullAttribute;
4047Handler = SanitizerHandler::NonnullReturn;
4049 if(
auto*DD = dyn_cast<DeclaratorDecl>(
CurCodeDecl))
4050 if(
auto*TSI = DD->getTypeSourceInfo())
4052AttrLoc = FTL.getReturnLoc().findNullabilityLoc();
4053CheckKind = SanitizerKind::SO_NullabilityReturn;
4054Handler = SanitizerHandler::NullabilityReturn;
4057SanitizerScope SanScope(
this);
4063llvm::Value *SLocPtr =
Builder.
CreateLoad(ReturnLocation,
"return.sloc.load");
4064llvm::Value *CanNullCheck =
Builder.CreateIsNotNull(SLocPtr);
4065 if(requiresReturnValueNullabilityCheck())
4067 Builder.CreateAnd(CanNullCheck, RetValNullabilityPrecondition);
4068 Builder.CreateCondBr(CanNullCheck, Check, NoCheck);
4072llvm::Value *Cond =
Builder.CreateIsNotNull(RV);
4074llvm::Value *DynamicData[] = {SLocPtr};
4075 EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, DynamicData);
4095llvm::Type *IRPtrTy = llvm::PointerType::getUnqual(CGF.
getLLVMContext());
4096llvm::Value *Placeholder = llvm::PoisonValue::get(IRPtrTy);
4123 if(
type->isReferenceType()) {
4132param->
hasAttr<NSConsumedAttr>() &&
4133 type->isObjCRetainableType()) {
4136llvm::ConstantPointerNull::get(cast<llvm::PointerType>(ptr->getType()));
4151CalleeDestructedParamCleanups.lookup(cast<ParmVarDecl>(param));
4153 "cleanup for callee-destructed param not recorded");
4155llvm::Instruction *isActive =
Builder.CreateUnreachable();
4161 returnllvm::isa_and_nonnull<llvm::ConstantPointerNull>(addr);
4174 "shouldn't have writeback for provably null argument");
4185llvm::BasicBlock *contBB =
nullptr;
4191 if(!provablyNonNull) {
4196CGF.
Builder.CreateCondBr(isNull, contBB, writebackBB);
4205 "icr.writeback-cast");
4214 if(writeback.
ToUse) {
4239 if(!provablyNonNull)
4248 for(
const auto&I : llvm::reverse(Cleanups)) {
4250I.IsActiveIP->eraseFromParent();
4256 if(uop->getOpcode() == UO_AddrOf)
4257 returnuop->getSubExpr();
4287llvm::PointerType *destType =
4289llvm::Type *destElemType =
4294args.
add(
RValue::get(llvm::ConstantPointerNull::get(destType)),
4306CodeGenFunction::ConditionalEvaluation condEval(CGF);
4312llvm::ConstantPointerNull::get(cast<llvm::PointerType>(destElemType));
4316llvm::BasicBlock *contBB =
nullptr;
4317llvm::BasicBlock *originBB =
nullptr;
4320llvm::Value *finalArgument;
4324 if(provablyNonNull) {
4329finalArgument = CGF.
Builder.CreateSelect(
4330isNull, llvm::ConstantPointerNull::get(destType),
4336originBB = CGF.
Builder.GetInsertBlock();
4339CGF.
Builder.CreateCondBr(isNull, contBB, copyBB);
4341condEval.begin(CGF);
4345llvm::Value *valueToUse =
nullptr;
4353src = CGF.
Builder.CreateBitCast(src, destElemType,
"icr.cast");
4370 if(shouldCopy && !provablyNonNull) {
4371llvm::BasicBlock *copyBB = CGF.
Builder.GetInsertBlock();
4376llvm::PHINode *phiToUse = CGF.
Builder.CreatePHI(valueToUse->getType(), 2,
4378phiToUse->addIncoming(valueToUse, copyBB);
4379phiToUse->addIncoming(llvm::PoisonValue::get(valueToUse->getType()),
4381valueToUse = phiToUse;
4395StackBase = CGF.
Builder.CreateStackSave(
"inalloca.save");
4401CGF.
Builder.CreateStackRestore(StackBase);
4409 if(!AC.getDecl() || !(
SanOpts.
has(SanitizerKind::NonnullAttribute) ||
4410 SanOpts.
has(SanitizerKind::NullabilityArg)))
4414 autoPVD = ParmNum < AC.getNumParams() ? AC.getParamDecl(ParmNum) :
nullptr;
4415 unsignedArgNo = PVD ? PVD->getFunctionScopeIndex() : ParmNum;
4418 constNonNullAttr *NNAttr =
nullptr;
4419 if(
SanOpts.
has(SanitizerKind::NonnullAttribute))
4422 boolCanCheckNullability =
false;
4423 if(
SanOpts.
has(SanitizerKind::NullabilityArg) && !NNAttr && PVD &&
4424!PVD->getType()->isRecordType()) {
4425 autoNullability = PVD->getType()->getNullability();
4426CanCheckNullability = Nullability &&
4428PVD->getTypeSourceInfo();
4431 if(!NNAttr && !CanCheckNullability)
4438AttrLoc = NNAttr->getLocation();
4439CheckKind = SanitizerKind::SO_NonnullAttribute;
4440Handler = SanitizerHandler::NonnullArg;
4442AttrLoc = PVD->getTypeSourceInfo()->getTypeLoc().findNullabilityLoc();
4443CheckKind = SanitizerKind::SO_NullabilityArg;
4444Handler = SanitizerHandler::NullabilityArg;
4447SanitizerScope SanScope(
this);
4449llvm::Constant *StaticData[] = {
4451llvm::ConstantInt::get(
Int32Ty, ArgNo + 1),
4453 EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, {});
4458AbstractCallee AC,
unsignedParmNum) {
4459 if(!AC.getDecl() || !(
SanOpts.
has(SanitizerKind::NonnullAttribute) ||
4460 SanOpts.
has(SanitizerKind::NullabilityArg)))
4479 returnllvm::any_of(ArgTypes, [&](
QualTypeTy) {
4490 returnclassDecl->getTypeParamListAsWritten();
4494 returncatDecl->getTypeParamList();
4504llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
4505AbstractCallee AC,
unsignedParamsToSkip, EvaluationOrder Order) {
4508assert((ParamsToSkip == 0 ||
Prototype.P) &&
4509 "Can't skip parameters if type info is not provided");
4519 boolIsVariadic =
false;
4521 const auto*MD = dyn_cast<const ObjCMethodDecl *>(
Prototype.P);
4523IsVariadic = MD->isVariadic();
4526ArgTypes.assign(MD->param_type_begin() + ParamsToSkip,
4527MD->param_type_end());
4529 const auto*FPT = cast<const FunctionProtoType *>(
Prototype.P);
4530IsVariadic = FPT->isVariadic();
4531ExplicitCC = FPT->getExtInfo().getCC();
4532ArgTypes.assign(FPT->param_type_begin() + ParamsToSkip,
4533FPT->param_type_end());
4541assert(Arg != ArgRange.end() &&
"Running over edge of argument list!");
4543(isGenericMethod || Ty->isVariablyModifiedType() ||
4544Ty.getNonReferenceType()->isObjCRetainableType() ||
4546.getCanonicalType(Ty.getNonReferenceType())
4548 getContext().getCanonicalType((*Arg)->getType()).getTypePtr()) &&
4549 "type mismatch in call argument!");
4555assert((Arg == ArgRange.end() || IsVariadic) &&
4556 "Extra arguments in non-variadic function!");
4561 for(
auto*A : llvm::drop_begin(ArgRange, ArgTypes.size()))
4562ArgTypes.push_back(IsVariadic ? getVarArgType(A) : A->getType());
4563assert((
int)ArgTypes.size() == (ArgRange.end() - ArgRange.begin()));
4575 autoMaybeEmitImplicitObjectSize = [&](
unsignedI,
const Expr*Arg,
4577 if(!AC.hasFunctionDecl() || I >= AC.getNumParams())
4579 auto*PS = AC.getParamDecl(I)->getAttr<PassObjectSizeAttr>();
4586assert(EmittedArg.getScalarVal() &&
"We emitted nothing for the arg?");
4587llvm::Value *
V= evaluateOrEmitBuiltinObjectSize(Arg, PS->getType(),
T,
4588EmittedArg.getScalarVal(),
4594std::swap(Args.back(), *(&Args.back() - 1));
4599assert(
getTarget().getTriple().getArch() == llvm::Triple::x86 &&
4600 "inalloca only supported on x86");
4605 size_tCallArgsStart = Args.size();
4606 for(
unsignedI = 0,
E= ArgTypes.size(); I !=
E; ++I) {
4607 unsignedIdx = LeftToRight ? I :
E- I - 1;
4609 unsignedInitialArgSize = Args.size();
4612assert((!isa<ObjCIndirectCopyRestoreExpr>(*Arg) ||
4613 getContext().hasSameUnqualifiedType((*Arg)->getType(),
4615(isa<ObjCMethodDecl>(AC.getDecl()) &&
4617 "Argument and parameter types don't match");
4621assert(InitialArgSize + 1 == Args.size() &&
4622 "The code below depends on only adding one arg per EmitCallArg");
4623(void)InitialArgSize;
4626 if(!Args.back().hasLValue()) {
4627 RValueRVArg = Args.back().getKnownRValue();
4629ParamsToSkip + Idx);
4633MaybeEmitImplicitObjectSize(Idx, *Arg, RVArg);
4640std::reverse(Args.begin() + CallArgsStart, Args.end());
4651: Addr(Addr), Ty(Ty) {}
4669structDisableDebugLocationUpdates {
4671 booldisabledDebugInfo;
4673 if((disabledDebugInfo = isa<CXXDefaultArgExpr>(
E) && CGF.
getDebugInfo()))
4676~DisableDebugLocationUpdates() {
4677 if(disabledDebugInfo)
4718DisableDebugLocationUpdates Dis(*
this,
E);
4720= dyn_cast<ObjCIndirectCopyRestoreExpr>(
E)) {
4734 "reference binding to unmaterialized r-value!");
4746 if(
type->isRecordType() &&
4753 boolDestroyedInCallee =
true, NeedsCleanup =
true;
4754 if(
const auto*RD =
type->getAsCXXRecordDecl())
4755DestroyedInCallee = RD->hasNonTrivialDestructor();
4757NeedsCleanup =
type.isDestructedType();
4759 if(DestroyedInCallee)
4766 if(DestroyedInCallee && NeedsCleanup) {
4773llvm::Instruction *IsActive =
4780 if(HasAggregateEvalKind && isa<ImplicitCastExpr>(
E) &&
4781cast<CastExpr>(
E)->getCastKind() == CK_LValueToRValue &&
4782!
type->isArrayParameterType()) {
4792QualTypeCodeGenFunction::getVarArgType(
const Expr*Arg) {
4796 if(!
getTarget().getTriple().isOSWindows())
4813CodeGenFunction::AddObjCARCExceptionMetadata(llvm::Instruction *Inst) {
4816Inst->setMetadata(
"clang.arc.no_objc_arc_exceptions",
4823 constllvm::Twine &name) {
4831 constllvm::Twine &name) {
4833 for(
autoarg : args)
4834values.push_back(
arg.emitRawPointer(*
this));
4841 constllvm::Twine &name) {
4843call->setDoesNotThrow();
4850 constllvm::Twine &name) {
4865 if(
auto*CalleeFn = dyn_cast<llvm::Function>(
Callee->stripPointerCasts())) {
4866 if(CalleeFn->isIntrinsic() && CalleeFn->doesNotThrow()) {
4867 autoIID = CalleeFn->getIntrinsicID();
4868 if(!llvm::IntrinsicInst::mayLowerToFunctionCall(IID))
4881 constllvm::Twine &name) {
4882llvm::CallInst *call =
Builder.CreateCall(
4887 returncast<llvm::CallInst>(addConvergenceControlToken(call));
4898llvm::InvokeInst *invoke =
4904invoke->setDoesNotReturn();
4907llvm::CallInst *call =
Builder.CreateCall(callee, args, BundleList);
4908call->setDoesNotReturn();
4917 constTwine &name) {
4925 constTwine &name) {
4935 constTwine &Name) {
4940llvm::CallBase *Inst;
4942Inst =
Builder.CreateCall(Callee, Args, BundleList, Name);
4945Inst =
Builder.CreateInvoke(Callee, ContBB, InvokeDest, Args, BundleList,
4953AddObjCARCExceptionMetadata(Inst);
4958voidCodeGenFunction::deferPlaceholderReplacement(llvm::Instruction *Old,
4960DeferredReplacements.push_back(
4961std::make_pair(llvm::WeakTrackingVH(Old), New));
4968[[nodiscard]] llvm::AttributeList
4969maybeRaiseRetAlignmentAttribute(llvm::LLVMContext &Ctx,
4970 constllvm::AttributeList &Attrs,
4971llvm::Align NewAlign) {
4972llvm::Align CurAlign = Attrs.getRetAlignment().valueOrOne();
4973 if(CurAlign >= NewAlign)
4975llvm::Attribute AlignAttr = llvm::Attribute::getWithAlignment(Ctx, NewAlign);
4976 returnAttrs.removeRetAttribute(Ctx, llvm::Attribute::AttrKind::Alignment)
4977.addRetAttribute(Ctx, AlignAttr);
4980template<
typenameAlignedAttrTy>
classAbstractAssumeAlignedAttrEmitter {
4985 constAlignedAttrTy *AA =
nullptr;
4987llvm::Value *Alignment =
nullptr;
4988llvm::ConstantInt *OffsetCI =
nullptr;
4994AA = FuncDecl->
getAttr<AlignedAttrTy>();
4999[[nodiscard]] llvm::AttributeList
5000TryEmitAsCallSiteAttribute(
constllvm::AttributeList &Attrs) {
5001 if(!AA || OffsetCI || CGF.
SanOpts.
has(SanitizerKind::Alignment))
5003 const auto*AlignmentCI = dyn_cast<llvm::ConstantInt>(Alignment);
5008 if(!AlignmentCI->getValue().isPowerOf2())
5010llvm::AttributeList NewAttrs = maybeRaiseRetAlignmentAttribute(
5013AlignmentCI->getLimitedValue(llvm::Value::MaximumAlignment)));
5025AA->getLocation(), Alignment, OffsetCI);
5031classAssumeAlignedAttrEmitter final
5032:
publicAbstractAssumeAlignedAttrEmitter<AssumeAlignedAttr> {
5035: AbstractAssumeAlignedAttrEmitter(CGF_, FuncDecl) {
5039Alignment = cast<llvm::ConstantInt>(CGF.
EmitScalarExpr(AA->getAlignment()));
5040 if(
Expr*Offset = AA->getOffset()) {
5041OffsetCI = cast<llvm::ConstantInt>(CGF.
EmitScalarExpr(Offset));
5042 if(OffsetCI->isNullValue())
5043OffsetCI =
nullptr;
5049classAllocAlignAttrEmitter final
5050:
publicAbstractAssumeAlignedAttrEmitter<AllocAlignAttr> {
5054: AbstractAssumeAlignedAttrEmitter(CGF_, FuncDecl) {
5058Alignment = CallArgs[AA->getParamIndex().getLLVMIndex()]
5067 if(
auto*VT = dyn_cast<llvm::VectorType>(Ty))
5068 returnVT->getPrimitiveSizeInBits().getKnownMinValue();
5069 if(
auto*AT = dyn_cast<llvm::ArrayType>(Ty))
5072 unsignedMaxVectorWidth = 0;
5073 if(
auto*ST = dyn_cast<llvm::StructType>(Ty))
5074 for(
auto*I : ST->elements())
5076 returnMaxVectorWidth;
5083llvm::CallBase **callOrInvoke,
boolIsMustTail,
5085 boolIsVirtualFunctionPointerThunk) {
5097 const Decl*TargetDecl =
Callee.getAbstractInfo().getCalleeDecl().getDecl();
5098 if(
const FunctionDecl*FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
5105 if(TargetDecl->
hasAttr<AlwaysInlineAttr>() &&
5106(TargetDecl->
hasAttr<TargetAttr>() ||
5114 const FunctionDecl*CalleeDecl = dyn_cast_or_null<FunctionDecl>(TargetDecl);
5116CalleeDecl, CallArgs, RetTy);
5123 if(llvm::StructType *ArgStruct = CallInfo.
getArgStruct()) {
5126llvm::AllocaInst *AI;
5128IP = IP->getNextNode();
5129AI =
newllvm::AllocaInst(ArgStruct, DL.getAllocaAddrSpace(),
"argmem",
5135AI->setAlignment(Align.getAsAlign());
5136AI->setUsedWithInAlloca(
true);
5137assert(AI->isUsedWithInAlloca() && !AI->isStaticAlloca());
5138ArgMemory =
RawAddress(AI, ArgStruct, Align);
5141ClangToLLVMArgMapping IRFunctionArgs(
CGM.
getContext(), CallInfo);
5148llvm::Value *UnusedReturnSizePtr =
nullptr;
5154 if((IsVirtualFunctionPointerThunk || IsMustTail) && RetAI.
isIndirect()) {
5156IRFunctionArgs.getSRetArgNo(),
5163llvm::TypeSize size =
5168 if(IRFunctionArgs.hasSRetArg()) {
5169IRCallArgs[IRFunctionArgs.getSRetArgNo()] =
5187assert(CallInfo.
arg_size() == CallArgs.size() &&
5188 "Mismatch between function signature & arguments.");
5191 for(CallArgList::const_iterator I = CallArgs.begin(),
E= CallArgs.end();
5192I !=
E; ++I, ++info_it, ++ArgNo) {
5196 if(IRFunctionArgs.hasPaddingArg(ArgNo))
5197IRCallArgs[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
5200 unsignedFirstIRArg, NumIRArgs;
5201std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
5203 boolArgHasMaybeUndefAttr =
5206 switch(ArgInfo.
getKind()) {
5208assert(NumIRArgs == 0);
5209assert(
getTarget().getTriple().getArch() == llvm::Triple::x86);
5210 if(I->isAggregate()) {
5212? I->getKnownLValue().getAddress()
5213: I->getKnownRValue().getAggregateAddress();
5214llvm::Instruction *Placeholder =
5215cast<llvm::Instruction>(Addr.
getPointer());
5219CGBuilderTy::InsertPoint IP =
Builder.saveIP();
5220 Builder.SetInsertPoint(Placeholder);
5233deferPlaceholderReplacement(Placeholder, Addr.
getPointer());
5238I->Ty,
getContext().getTypeAlignInChars(I->Ty),
5239 "indirect-arg-temp");
5240I->copyInto(*
this, Addr);
5249I->copyInto(*
this, Addr);
5256assert(NumIRArgs == 1);
5257 if(I->isAggregate()) {
5267? I->getKnownLValue().getAddress()
5268: I->getKnownRValue().getAggregateAddress();
5272assert((FirstIRArg >= IRFuncTy->getNumParams() ||
5273IRFuncTy->getParamType(FirstIRArg)->getPointerAddressSpace() ==
5274TD->getAllocaAddrSpace()) &&
5275 "indirect argument must be in alloca address space");
5277 boolNeedCopy =
false;
5283}
else if(I->hasLValue()) {
5284 autoLV = I->getKnownLValue();
5290 if(!isByValOrRef ||
5295 if((isByValOrRef &&
5303 else if((isByValOrRef &&
5304Addr.
getType()->getAddressSpace() != IRFuncTy->
5305 getParamType(FirstIRArg)->getPointerAddressSpace())) {
5313 auto*
T= llvm::PointerType::get(
5319 if(ArgHasMaybeUndefAttr)
5320Val =
Builder.CreateFreeze(Val);
5321IRCallArgs[FirstIRArg] = Val;
5324}
else if(I->getType()->isArrayParameterType()) {
5330IRCallArgs[FirstIRArg] = I->getKnownRValue().getScalarVal();
5339 if(ArgHasMaybeUndefAttr)
5340Val =
Builder.CreateFreeze(Val);
5341IRCallArgs[FirstIRArg] = Val;
5344llvm::TypeSize ByvalTempElementSize =
5346llvm::Value *LifetimeSize =
5351CallLifetimeEndAfterCall.emplace_back(AI, LifetimeSize);
5354I->copyInto(*
this, AI);
5359assert(NumIRArgs == 0);
5367assert(NumIRArgs == 1);
5369 if(!I->isAggregate())
5370 V= I->getKnownRValue().getScalarVal();
5373I->hasLValue() ? I->getKnownLValue().getAddress()
5374: I->getKnownRValue().getAggregateAddress());
5380assert(!swiftErrorTemp.
isValid() &&
"multiple swifterror args");
5384 V, pointeeTy,
getContext().getTypeAlignInChars(pointeeTy));
5389cast<llvm::AllocaInst>(
V)->setSwiftError(
true);
5397 V->getType()->isIntegerTy())
5402 if(FirstIRArg < IRFuncTy->getNumParams() &&
5403 V->getType() != IRFuncTy->getParamType(FirstIRArg))
5404 V=
Builder.CreateBitCast(
V, IRFuncTy->getParamType(FirstIRArg));
5406 if(ArgHasMaybeUndefAttr)
5408IRCallArgs[FirstIRArg] =
V;
5412llvm::StructType *STy =
5417 if(!I->isAggregate()) {
5419I->copyInto(*
this, Src);
5421Src = I->hasLValue() ? I->getKnownLValue().getAddress()
5422: I->getKnownRValue().getAggregateAddress();
5432llvm::TypeSize SrcTypeSize =
5435 if(SrcTypeSize.isScalable()) {
5436assert(STy->containsHomogeneousScalableVectorTypes() &&
5437 "ABI only supports structure with homogeneous scalable vector " 5439assert(SrcTypeSize == DstTypeSize &&
5440 "Only allow non-fractional movement of structure with " 5441 "homogeneous scalable vector type");
5442assert(NumIRArgs == STy->getNumElements());
5444llvm::Value *StoredStructValue =
5446 for(
unsignedi = 0, e = STy->getNumElements(); i != e; ++i) {
5447llvm::Value *Extract =
Builder.CreateExtractValue(
5448StoredStructValue, i, Src.
getName() +
".extract"+ Twine(i));
5449IRCallArgs[FirstIRArg + i] = Extract;
5452 uint64_tSrcSize = SrcTypeSize.getFixedValue();
5453 uint64_tDstSize = DstTypeSize.getFixedValue();
5459 if(SrcSize < DstSize) {
5461Src.
getName() +
".coerce");
5468assert(NumIRArgs == STy->getNumElements());
5469 for(
unsignedi = 0, e = STy->getNumElements(); i != e; ++i) {
5472 if(ArgHasMaybeUndefAttr)
5473LI =
Builder.CreateFreeze(LI);
5474IRCallArgs[FirstIRArg + i] = LI;
5479assert(NumIRArgs == 1);
5480llvm::Value *
Load=
5487 auto*ATy = dyn_cast<llvm::ArrayType>(
Load->getType());
5488 if(ATy !=
nullptr&& isa<RecordType>(I->Ty.getCanonicalType()))
5492 if(ArgHasMaybeUndefAttr)
5494IRCallArgs[FirstIRArg] =
Load;
5504 auto*unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
5506llvm::Value *tempSize =
nullptr;
5509 if(I->isAggregate()) {
5510addr = I->hasLValue() ? I->getKnownLValue().getAddress()
5511: I->getKnownRValue().getAggregateAddress();
5514 RValueRV = I->getKnownRValue();
5517llvm::Type *scalarType = RV.
getScalarVal()->getType();
5526 nullptr, &AllocaAddr);
5534 unsignedIRArgPos = FirstIRArg;
5535 unsignedunpaddedIndex = 0;
5536 for(
unsignedi = 0, e = coercionType->getNumElements(); i != e; ++i) {
5537llvm::Type *eltType = coercionType->getElementType(i);
5542unpaddedStruct ? unpaddedStruct->getElementType(unpaddedIndex++)
5543: unpaddedCoercionType,
5545 if(ArgHasMaybeUndefAttr)
5546elt =
Builder.CreateFreeze(elt);
5547IRCallArgs[IRArgPos++] = elt;
5549assert(IRArgPos == FirstIRArg + NumIRArgs);
5559 unsignedIRArgPos = FirstIRArg;
5560ExpandTypeToArgs(I->Ty, *I, IRFuncTy, IRCallArgs, IRArgPos);
5561assert(IRArgPos == FirstIRArg + NumIRArgs);
5567 const CGCallee&ConcreteCallee =
Callee.prepareConcreteCallee(*
this);
5573assert(IRFunctionArgs.hasInallocaArg());
5574IRCallArgs[IRFunctionArgs.getInallocaArgNo()] = Arg;
5585 autosimplifyVariadicCallee = [](llvm::FunctionType *CalleeFT,
5586llvm::Value *Ptr) -> llvm::Function * {
5587 if(!CalleeFT->isVarArg())
5591 if(llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Ptr)) {
5592 if(CE->getOpcode() == llvm::Instruction::BitCast)
5593Ptr = CE->getOperand(0);
5596llvm::Function *OrigFn = dyn_cast<llvm::Function>(Ptr);
5600llvm::FunctionType *OrigFT = OrigFn->getFunctionType();
5604 if(OrigFT->isVarArg() ||
5605OrigFT->getNumParams() != CalleeFT->getNumParams() ||
5606OrigFT->getReturnType() != CalleeFT->getReturnType())
5609 for(
unsignedi = 0, e = OrigFT->getNumParams(); i != e; ++i)
5610 if(OrigFT->getParamType(i) != CalleeFT->getParamType(i))
5616 if(llvm::Function *OrigFn = simplifyVariadicCallee(IRFuncTy, CalleePtr)) {
5618IRFuncTy = OrigFn->getFunctionType();
5633assert(IRCallArgs.size() == IRFuncTy->getNumParams() || IRFuncTy->isVarArg());
5634 for(
unsignedi = 0; i < IRCallArgs.size(); ++i) {
5636 if(IRFunctionArgs.hasInallocaArg() &&
5637i == IRFunctionArgs.getInallocaArgNo())
5639 if(i < IRFuncTy->getNumParams())
5640assert(IRCallArgs[i]->getType() == IRFuncTy->getParamType(i));
5645 for(
unsignedi = 0; i < IRCallArgs.size(); ++i)
5646LargestVectorWidth = std::max(LargestVectorWidth,
5651llvm::AttributeList Attrs;
5657 if(
CallingConv== llvm::CallingConv::X86_VectorCall &&
5658 getTarget().getTriple().isWindowsArm64EC()) {
5659 CGM.
Error(
Loc,
"__vectorcall calling convention is not currently " 5664 if(FD->hasAttr<StrictFPAttr>())
5666Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::StrictFP);
5671 if(FD->hasAttr<OptimizeNoneAttr>() &&
getLangOpts().FastMath)
5677Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::NoMerge);
5681Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::NoInline);
5687CallerDecl, CalleeDecl))
5689Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::AlwaysInline);
5694Attrs.removeFnAttribute(
getLLVMContext(), llvm::Attribute::Convergent);
5703!(TargetDecl && TargetDecl->
hasAttr<NoInlineAttr>()) &&
5705CallerDecl, CalleeDecl)) {
5707Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::AlwaysInline);
5712Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::NoInline);
5719CannotThrow =
false;
5725CannotThrow =
true;
5728CannotThrow = Attrs.hasFnAttr(llvm::Attribute::NoUnwind);
5730 if(
auto*FPtr = dyn_cast<llvm::Function>(CalleePtr))
5731 if(FPtr->hasFnAttribute(llvm::Attribute::NoUnwind))
5732CannotThrow =
true;
5739 if(UnusedReturnSizePtr)
5741UnusedReturnSizePtr);
5743llvm::BasicBlock *InvokeDest = CannotThrow ? nullptr :
getInvokeDest();
5749!isa_and_nonnull<FunctionDecl>(TargetDecl))
5756 if(FD->hasAttr<StrictFPAttr>())
5758Attrs = Attrs.addFnAttribute(
getLLVMContext(), llvm::Attribute::StrictFP);
5760AssumeAlignedAttrEmitter AssumeAlignedAttrEmitter(*
this, TargetDecl);
5761Attrs = AssumeAlignedAttrEmitter.TryEmitAsCallSiteAttribute(Attrs);
5763AllocAlignAttrEmitter AllocAlignAttrEmitter(*
this, TargetDecl, CallArgs);
5764Attrs = AllocAlignAttrEmitter.TryEmitAsCallSiteAttribute(Attrs);
5769CI =
Builder.CreateCall(IRFuncTy, CalleePtr, IRCallArgs, BundleList);
5772CI =
Builder.CreateInvoke(IRFuncTy, CalleePtr, Cont, InvokeDest, IRCallArgs,
5776 if(CI->getCalledFunction() && CI->getCalledFunction()->hasName() &&
5777CI->getCalledFunction()->getName().starts_with(
"_Z4sqrt")) {
5786 if(
const auto*FD = dyn_cast_or_null<FunctionDecl>(
CurFuncDecl)) {
5787 if(
const auto*A = FD->getAttr<CFGuardAttr>()) {
5788 if(A->getGuard() == CFGuardAttr::GuardArg::nocf && !CI->getCalledFunction())
5794CI->setAttributes(Attrs);
5795CI->setCallingConv(
static_cast<llvm::CallingConv::ID
>(
CallingConv));
5799 if(!CI->getType()->isVoidTy())
5800CI->setName(
"call");
5803CI = addConvergenceControlToken(CI);
5806LargestVectorWidth =
5812 if(!CI->getCalledFunction())
5819AddObjCARCExceptionMetadata(CI);
5822 if(llvm::CallInst *
Call= dyn_cast<llvm::CallInst>(CI)) {
5823 if(TargetDecl && TargetDecl->
hasAttr<NotTailCalledAttr>())
5824 Call->setTailCallKind(llvm::CallInst::TCK_NoTail);
5825 else if(IsMustTail) {
5826 if(
getTarget().getTriple().isPPC()) {
5827 if(
getTarget().getTriple().isOSAIX())
5832 else if(
Call->isIndirectCall())
5834 else if(isa_and_nonnull<FunctionDecl>(TargetDecl)) {
5835 if(!cast<FunctionDecl>(TargetDecl)->isDefined())
5840{cast<FunctionDecl>(TargetDecl),
Loc});
5843 GlobalDecl(cast<FunctionDecl>(TargetDecl)));
5844 if(llvm::GlobalValue::isWeakForLinker(
Linkage) ||
5845llvm::GlobalValue::isDiscardableIfUnused(
Linkage))
5852 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
5858TargetDecl->
hasAttr<MSAllocatorAttr>())
5862 if(TargetDecl && TargetDecl->
hasAttr<ErrorAttr>()) {
5863llvm::ConstantInt *
Line=
5865llvm::ConstantAsMetadata *MD = llvm::ConstantAsMetadata::get(
Line);
5866llvm::MDTuple *MDT = llvm::MDNode::get(
getLLVMContext(), {MD});
5867CI->setMetadata(
"srcloc", MDT);
5875 if(CI->doesNotReturn()) {
5876 if(UnusedReturnSizePtr)
5880 if(
SanOpts.
has(SanitizerKind::Unreachable)) {
5883 if(
auto*F = CI->getCalledFunction())
5884F->removeFnAttr(llvm::Attribute::NoReturn);
5885CI->removeFnAttr(llvm::Attribute::NoReturn);
5890SanitizerKind::KernelAddress)) {
5891SanitizerScope SanScope(
this);
5892llvm::IRBuilder<>::InsertPointGuard IPGuard(
Builder);
5894 auto*FnType = llvm::FunctionType::get(
CGM.
VoidTy,
false);
5895llvm::FunctionCallee
Fn=
5902 Builder.ClearInsertionPoint();
5922 if(CI->getType()->isVoidTy())
5926 Builder.ClearInsertionPoint();
5932 if(swiftErrorTemp.
isValid()) {
5951 if(IsVirtualFunctionPointerThunk) {
5962 boolrequiresExtract = isa<llvm::StructType>(CI->getType());
5964 unsignedunpaddedIndex = 0;
5965 for(
unsignedi = 0, e = coercionType->getNumElements(); i != e; ++i) {
5966llvm::Type *eltType = coercionType->getElementType(i);
5970llvm::Value *elt = CI;
5971 if(requiresExtract)
5972elt =
Builder.CreateExtractValue(elt, unpaddedIndex++);
5974assert(unpaddedIndex == 0);
5983 if(UnusedReturnSizePtr)
6000llvm::Value *Real =
Builder.CreateExtractValue(CI, 0);
6001llvm::Value *Imag =
Builder.CreateExtractValue(CI, 1);
6009llvm::Value *
V= CI;
6010 if(
V->getType() != RetIRTy)
6011 V=
Builder.CreateBitCast(
V, RetIRTy);
6020 if(
auto*FixedDstTy = dyn_cast<llvm::FixedVectorType>(RetIRTy)) {
6021llvm::Value *
V= CI;
6022 if(
auto*ScalableSrcTy =
6023dyn_cast<llvm::ScalableVectorType>(
V->getType())) {
6024 if(FixedDstTy->getElementType() ==
6025ScalableSrcTy->getElementType()) {
6026llvm::Value *
Zero= llvm::Constant::getNullValue(
CGM.
Int64Ty);
6027 V=
Builder.CreateExtractVector(FixedDstTy,
V, Zero,
6041DestIsVolatile =
false;
6062llvm_unreachable(
"Invalid ABI kind for return argument");
6065llvm_unreachable(
"Unhandled ABIArgInfo::Kind");
6070 if(
Ret.isScalar() && TargetDecl) {
6071AssumeAlignedAttrEmitter.EmitAsAnAssumption(
Loc, RetTy, Ret);
6072AllocAlignAttrEmitter.EmitAsAnAssumption(
Loc, RetTy, Ret);
6077 for(CallLifetimeEnd &LifetimeEnd : CallLifetimeEndAfterCall)
6078LifetimeEnd.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 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 std::pair< llvm::Value *, bool > CoerceScalableToFixed(CodeGenFunction &CGF, llvm::FixedVectorType *ToTy, llvm::ScalableVectorType *FromTy, llvm::Value *V, StringRef Name="")
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
enum clang::sema::@1704::IndirectLocalPathEntry::EntryKind Kind
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
llvm::MachO::Target Target
static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, const TargetInfo &Target)
Determine whether a translation unit built using the current language options has the given feature.
static QualType getParamType(Sema &SemaRef, ArrayRef< ResultCandidate > Candidates, unsigned N)
Get the type of the Nth parameter from a given set of overload candidates.
static QualType getPointeeType(const MemRegion *R)
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 getTypeInfoDataSizeInChars(QualType T) const
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 RValue EmitMSVAArg(CodeGen::CodeGenFunction &CGF, CodeGen::Address VAListAddr, QualType Ty, AggValueSlot Slot) const
Emit the target dependent code to load a value of.
virtual RValue EmitVAArg(CodeGen::CodeGenFunction &CGF, CodeGen::Address VAListAddr, QualType Ty, AggValueSlot Slot) 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::LoadInst * CreateFlagLoad(llvm::Value *Addr, const llvm::Twine &Name="")
Emit a load from an i1 flag variable.
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
Implements C++ ABI-specific code generation functions.
virtual bool hasMostDerivedReturn(GlobalDecl GD) const
virtual bool HasThisReturn(GlobalDecl GD) const
Returns true if the given constructor or destructor is one of the kinds that the ABI says returns 'th...
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
virtual CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD, Address This, llvm::Type *Ty, SourceLocation Loc)=0
Build a virtual function pointer in the ABI-specific way.
virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const =0
Returns how an argument of the given record type should be passed.
virtual const CXXRecordDecl * getThisArgumentTypeForMethod(GlobalDecl GD)
Get the type of the implicit "this" parameter used by a method.
virtual AddedStructorArgCounts buildStructorSignature(GlobalDecl GD, SmallVectorImpl< CanQualType > &ArgTys)=0
Build the signature of the given constructor or destructor variant by adding any required parameters.
Abstract information about a function or function prototype.
const GlobalDecl getCalleeDecl() const
const FunctionProtoType * getCalleeFunctionProtoType() const
All available information about a concrete callee.
CGCallee prepareConcreteCallee(CodeGenFunction &CGF) const
If this is a delayed callee computation of some sort, prepare a concrete callee.
Address getThisAddress() const
const CallExpr * getVirtualCallExpr() const
llvm::Value * getFunctionPointer() const
llvm::FunctionType * getVirtualFunctionType() const
const CGPointerAuthInfo & getPointerAuthInfo() const
GlobalDecl getVirtualMethodDecl() const
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, const Expr *writebackExpr=nullptr, llvm::Value *lifetimeSz=nullptr)
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
void CreateCoercedStore(llvm::Value *Src, Address Dst, llvm::TypeSize DstSize, bool DstIsVolatile)
Create a store to.
llvm::Value * EmitLifetimeStart(llvm::TypeSize Size, llvm::Value *Addr)
void EmitPointerAuthOperandBundle(const CGPointerAuthInfo &Info, SmallVectorImpl< llvm::OperandBundleDef > &Bundles)
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.
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)
LValue EmitHLSLOutArgExpr(const HLSLOutArgExpr *E, CallArgList &Args, QualType Ty)
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)
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
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.
bool InNoConvergentAttributedStmt
True if the current statement has noconvergent attribute.
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)
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
bool InNoMergeAttributedStmt
True if the current statement has nomerge attribute.
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()
llvm::Value * EmitARCRetainAutoreleaseReturnValue(llvm::Value *value)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > 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...
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 SetSqrtFPAccuracy(llvm::Value *Val)
Set the minimum required accuracy of the given sqrt operation based on CodeGenOpts.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr, AggValueSlot Slot=AggValueSlot::ignored())
Generate code to get an argument from the passed in pointer and update it accordingly.
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)
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
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)
void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args)
CodeGenTypes & getTypes() const
void EmitWritebacks(const CallArgList &Args)
EmitWriteback - Emit callbacks for function.
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.
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
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
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.
const ABIInfo & getABIInfo()
bool ReturnTypeUsesFPRet(QualType ResultType)
Return true iff the given type uses 'fpret' when used as a return type.
DiagnosticsEngine & getDiags() const
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
void addUndefinedGlobalForTailCall(std::pair< const FunctionDecl *, SourceLocation > Global)
ObjCEntrypoints & getObjCEntrypoints() const
void Error(SourceLocation loc, StringRef error)
Emit a general error that something can't be done.
bool shouldEmitConvergenceTokens() const
CGCXXABI & getCXXABI() const
bool ReturnTypeUsesFP2Ret(QualType ResultType)
Return true iff the given type uses 'fp2ret' when used as a return type.
llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD)
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.
CGCXXABI & getCXXABI() const
const CGFunctionInfo & arrangeCXXMethodDeclaration(const CXXMethodDecl *MD)
C++ methods have some special rules and also have implicit parameters.
ASTContext & getContext() const
const CGFunctionInfo & arrangeLLVMFunctionInfo(CanQualType returnType, FnInfoOpts opts, ArrayRef< CanQualType > argTypes, FunctionType::ExtInfo info, ArrayRef< FunctionProtoType::ExtParameterInfo > paramInfos, RequiredArgs args)
"Arrange" the LLVM information for a call or type with the given signature.
const CGFunctionInfo & arrangeFreeFunctionType(CanQual< FunctionProtoType > Ty)
Arrange the argument and result information for a value of the given freestanding function type.
CanQualType DeriveThisType(const CXXRecordDecl *RD, const CXXMethodDecl *MD)
Derives the 'this' type for codegen purposes, i.e.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
bool inheritingCtorHasParams(const InheritedConstructor &Inherited, CXXCtorType Type)
Determine if a C++ inheriting constructor should have parameters matching those of its inherited cons...
bool isFuncTypeConvertible(const FunctionType *FT)
isFuncTypeConvertible - Utility to check whether a function type can be converted to an LLVM type (i....
const CGFunctionInfo & arrangeBlockFunctionCall(const CallArgList &args, const FunctionType *type)
A block function is essentially a free function with an extra implicit argument.
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
const CGFunctionInfo & arrangeUnprototypedObjCMessageSend(QualType returnType, const CallArgList &args)
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
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
static LValue MakeAddr(Address Addr, QualType type, ASTContext &Context, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo)
Address getAddress() const
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 bool wouldInliningViolateFunctionCallABI(const FunctionDecl *Caller, const FunctionDecl *Callee) const
Returns true if inlining the function call would produce incorrect code for the current target and sh...
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 void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, const FunctionDecl *Callee, const CallArgList &Args, QualType ReturnType) const
Any further codegen related checks that need to be done on a function call in a target specific manne...
virtual unsigned getOpenCLKernelCallingConv() const
Get LLVM calling convention for OpenCL kernel.
static void initBranchProtectionFnAttributes(const TargetInfo::BranchProtectionInfo &BPI, llvm::AttrBuilder &FuncAttrs)
virtual bool isNoProtoCallVariadic(const CodeGen::CallArgList &args, const FunctionNoProtoType *fnType) const
Determine whether a call to an unprototyped functions under the given calling convention should use t...
Complex values, per C99 6.2.5p11.
Represents the canonical version of C arrays with a specified constant size.
bool constructsVirtualBase() const
Returns true if the constructed base class is a virtual base class subobject of this declaration's cl...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Decl - This represents one declaration (or definition), e.g.
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
This represents one expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
bool isZeroLengthBitField() const
Is this a zero-length bit-field? Such bit-fields aren't really bit-fields at all and instead act as a...
Represents a function declaration or definition.
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Represents a prototype with parameter type info, e.g.
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
unsigned getNumParams() const
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
ArrayRef< ExtParameterInfo > getExtParameterInfos() const
bool hasExtParameterInfos() const
Is there any interesting extra information for any of the parameters of this function type?
Wrapper for source info for functions.
A class which abstracts out some details necessary for making a call.
ExtInfo withCallingConv(CallingConv cc) const
CallingConv getCC() const
ExtInfo withProducesResult(bool producesResult) const
bool getCmseNSCall() const
bool getNoCfCheck() const
unsigned getRegParm() const
bool getNoCallerSavedRegs() const
bool getHasRegParm() const
bool getProducesResult() const
Interesting information about a specific parameter that can't simply be reflected in parameter's type...
ParameterABI getABI() const
Return the ABI treatment of this parameter.
ExtParameterInfo withIsNoEscape(bool NoEscape) const
FunctionType - C99 6.7.5.3 - Function Declarators.
ExtInfo getExtInfo() const
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
QualType getReturnType() const
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
@ SME_AgnosticZAStateMask
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
const Decl * getDecl() const
This class represents temporary values used to represent inout and out arguments in HLSL.
Description of a constructor that was inherited from a base class.
ConstructorUsingShadowDecl * getShadowDecl() const
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
std::vector< std::string > NoBuiltinFuncs
A list of all -fno-builtin-* function names (e.g., memset).
FPExceptionModeKind getDefaultExceptionMode() const
bool isNoBuiltinFunc(StringRef Name) const
Is this a libc/libm function that is no longer recognized as a builtin because a -fno-builtin-* optio...
bool assumeFunctionsAreConvergent() const
Represents a matrix type, as defined in the Matrix Types clang extensions.
Describes a module or submodule.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
ObjCCategoryDecl - Represents a category declaration.
ObjCIndirectCopyRestoreExpr - Represents the passing of a function argument by indirect copy-restore ...
bool shouldCopy() const
shouldCopy - True if we should do the 'copy' part of the copy-restore.
Represents an ObjC class declaration.
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
ArrayRef< ParmVarDecl * > parameters() const
bool isDirectMethod() const
True if the method is tagged as objc_direct.
QualType getReturnType() const
Represents a parameter to a function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
bool isRestrictQualified() const
Determine whether this type is restrict-qualified.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType 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 isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isObjectType() const
Determine whether this type is an object type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
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...
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.
tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName="<stdin>")
Clean up any erroneous/redundant code in the given Ranges in Code.
bool This(InterpState &S, CodePtr OpPC)
bool Zero(InterpState &S, CodePtr OpPC)
bool Load(InterpState &S, CodePtr OpPC)
bool Ret(InterpState &S, CodePtr &PC)
RangeSelector name(std::string ID)
Given a node with a "name", (like NamedDecl, DeclRefExpr, CxxCtorInitializer, and TypeLoc) selects th...
The JSON file list parser is used to communicate input to InstallAPI.
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)
bool isInstanceMethod(const Decl *D)
@ NonNull
Values of this type can never be null.
@ OK_Ordinary
An ordinary object is located at an address in memory.
@ Vector
'vector' clause, allowed on 'loop', Combined, and 'routine' directives.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
@ 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.
const Expr * WritebackExpr
An Expression (optional) that performs the writeback with any required casting.
LValue getKnownLValue() const
RValue getKnownRValue() const
void copyInto(CodeGenFunction &CGF, Address A) const
RValue getRValue(CodeGenFunction &CGF) const
llvm::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
llvm::PointerType * Int8PtrTy
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 *.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4