19#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
20#include "mlir/IR/Attributes.h"
25#include "llvm/ADT/FloatingPointMode.h"
26#include "llvm/ADT/StringSet.h"
27#include "llvm/Support/TypeSize.h"
38 void *buffer =
operator new(
39 totalSizeToAlloc<CanQualType>(
argTypes.size() + 1));
43 CIRGenFunctionInfo *fi =
new (buffer) CIRGenFunctionInfo();
45 fi->callingConvention = llvm::to_underlying(cirCC);
46 fi->astCallingConvention = info.getCC();
47 fi->noReturn = info.getNoReturn();
50 fi->required = required;
57 assert((!required.allowsOptionalArgs() ||
58 required.getNumRequiredArgs() <= fi->numArgs) &&
59 "more required arguments than argument types");
61 fi->getArgTypes()[0] = resultType;
74 mlir::Type resultType =
convertType(info.getReturnType());
76 argTypes.reserve(info.getNumRequiredArgs());
78 for (
const CanQualType &argType : info.requiredArguments())
81 return cir::FuncType::get(argTypes,
82 (resultType ? resultType : builder.getVoidTy()),
108 mlir::OpBuilder::InsertionGuard guard(builder);
109 builder.setInsertionPointAfter(value.getDefiningOp());
114 mlir::NamedAttrList &attrs,
121 attrs.set(cir::CIRDialect::getNoThrowAttrName(),
122 mlir::UnitAttr::get(builder.getContext()));
126 mlir::NamedAttrList &attrs,
128 const NoBuiltinAttr *nba =
nullptr) {
132 if (langOpts.NoBuiltin ||
133 (nba && llvm::is_contained(nba->builtinNames(),
"*"))) {
136 attrs.set(cir::CIRDialect::getNoBuiltinsAttrName(),
137 mlir::ArrayAttr::get(&ctx, {}));
141 llvm::SetVector<mlir::Attribute> nbFuncs;
142 auto addNoBuiltinAttr = [&ctx, &nbFuncs](StringRef builtinName) {
143 nbFuncs.insert(mlir::StringAttr::get(&ctx, builtinName));
152 llvm::for_each(nba->builtinNames(), addNoBuiltinAttr);
154 if (!nbFuncs.empty())
155 attrs.set(cir::CIRDialect::getNoBuiltinsAttrName(),
156 mlir::ArrayAttr::get(&ctx, nbFuncs.getArrayRef()));
163 llvm::DenormalMode fp32DenormalMode,
164 mlir::NamedAttrList &attrs) {
176 mlir::NamedAttrList &attrs) {
181static llvm::StringLiteral
184 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Skip:
185 llvm_unreachable(
"No string value, shouldn't be able to get here");
186 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPRArg:
187 return "used-gpr-arg";
188 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPR:
190 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedArg:
192 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Used:
194 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPRArg:
195 return "all-gpr-arg";
196 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPR:
198 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllArg:
200 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::All:
204 llvm_unreachable(
"Unknown kind?");
207std::optional<cir::FramePointerKind>
213 return cir::FramePointerKind::Reserved;
215 return cir::FramePointerKind::NonLeafNoReserve;
217 return cir::FramePointerKind::NonLeaf;
219 return cir::FramePointerKind::All;
221 llvm_unreachable(
"Unknown frame pointer kind");
228 mlir::MLIRContext *mlirCtx, StringRef name,
bool hasOptNoneAttr,
230 bool attrOnCallSite, mlir::NamedAttrList &attrs) {
233 if (!hasOptNoneAttr) {
234 if (codeGenOpts.OptimizeSize)
235 attrs.set(cir::CIRDialect::getOptimizeForSizeAttrName(),
236 mlir::UnitAttr::get(mlirCtx));
237 if (codeGenOpts.OptimizeSize == 2)
238 attrs.set(cir::CIRDialect::getMinSizeAttrName(),
239 mlir::UnitAttr::get(mlirCtx));
245 if (attrOnCallSite) {
248 attrs.set(cir::CIRDialect::getNoBuiltinAttrName(),
249 mlir::UnitAttr::get(mlirCtx));
252 attrs.set(cir::CIRDialect::getTrapFuncNameAttrName(),
253 mlir::StringAttr::get(mlirCtx, codeGenOpts.
TrapFuncName));
255 if (std::optional<cir::FramePointerKind>
kind =
257 attrs.set(cir::CIRDialect::getFramePointerAttrName(),
258 cir::FramePointerKindAttr::get(mlirCtx, *
kind));
272 if (codeGenOpts.getZeroCallUsedRegs() ==
273 llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Skip)
274 attrs.erase(cir::CIRDialect::getZeroCallUsedRegsAttrName());
276 attrs.set(cir::CIRDialect::getZeroCallUsedRegsAttrName(),
277 mlir::StringAttr::get(mlirCtx,
279 codeGenOpts.getZeroCallUsedRegs())));
288 attrs.set(cir::CIRDialect::getConvergentAttrName(),
289 mlir::UnitAttr::get(mlirCtx));
295 if ((langOpts.CUDA && langOpts.CUDAIsDevice) || langOpts.OpenCL ||
296 langOpts.SYCLIsDevice) {
297 attrs.set(cir::CIRDialect::getNoThrowAttrName(),
298 mlir::UnitAttr::get(mlirCtx));
299 attrs.set(cir::CIRDialect::getNoUnwindAttrName(),
300 mlir::UnitAttr::get(mlirCtx));
303 if (codeGenOpts.SaveRegParams && !attrOnCallSite)
304 attrs.set(cir::CIRDialect::getSaveRegParamsAttrName(),
305 mlir::UnitAttr::get(mlirCtx));
314 [mlirCtx](llvm::StringRef arg) {
315 auto [var, value] = arg.split(
'=');
318 ? cast<mlir::Attribute>(mlir::UnitAttr::get(mlirCtx))
319 : cast<mlir::Attribute>(mlir::StringAttr::get(mlirCtx, value));
320 return mlir::NamedAttribute(var, valueAttr);
323 if (!defaultFuncAttrs.empty())
324 attrs.set(cir::CIRDialect::getDefaultFuncAttrsAttrName(),
325 mlir::DictionaryAttr::get(mlirCtx, defaultFuncAttrs));
337 mlir::NamedAttrList &attrs) {
340 codeGenOpts, langOpts, attrOnCallSite,
343 if (!attrOnCallSite) {
356 mlir::NamedAttrList &retAttrs, cir::CallingConv &callingConv,
357 bool attrOnCallSite,
bool isThunk) {
358 callingConv = info.getCallingConvention();
360 auto addUnitAttr = [&](llvm::StringRef name) {
364 if (info.isNoReturn())
365 addUnitAttr(cir::CIRDialect::getNoReturnAttrName());
374 const Decl *targetDecl = targetGlobalDecl.
getDecl();
378 const NoBuiltinAttr *nba =
nullptr;
384 if (targetDecl->
hasAttr<NoThrowAttr>())
385 addUnitAttr(cir::CIRDialect::getNoThrowAttrName());
390 if (targetDecl->
hasAttr<NoReturnAttr>())
391 addUnitAttr(cir::CIRDialect::getNoReturnAttrName());
392 if (targetDecl->
hasAttr<ReturnsTwiceAttr>())
393 addUnitAttr(cir::CIRDialect::getReturnsTwiceAttrName());
394 if (targetDecl->
hasAttr<ColdAttr>())
395 addUnitAttr(cir::CIRDialect::getColdAttrName());
396 if (targetDecl->
hasAttr<HotAttr>())
397 addUnitAttr(cir::CIRDialect::getHotAttrName());
398 if (targetDecl->
hasAttr<NoDuplicateAttr>())
399 addUnitAttr(cir::CIRDialect::getNoDuplicatesAttrName());
400 if (targetDecl->
hasAttr<ConvergentAttr>())
401 addUnitAttr(cir::CIRDialect::getConvergentAttrName());
403 if (
const FunctionDecl *func = dyn_cast<FunctionDecl>(targetDecl)) {
408 if (attrOnCallSite && func->isReplaceableGlobalAllocationFunction() &&
409 codeGenOpts.AssumeSaneOperatorNew &&
410 func->getDeclName().isAnyOperatorNew()) {
411 retAttrs.set(mlir::LLVM::LLVMDialect::getNoAliasAttrName(),
423 if (func->isNoReturn())
424 addUnitAttr(cir::CIRDialect::getNoReturnAttrName());
425 nba = func->getAttr<NoBuiltinAttr>();
431 auto setMemoryEffects = [&](cir::MemoryEffectsAttr effects) {
432 attrs.set(cir::CIRDialect::getMemoryEffectsAttrName(), effects);
436 if (targetDecl->
hasAttr<ConstAttr>()) {
437 setMemoryEffects(cir::MemoryEffectsAttr::none(&
getMLIRContext()));
438 addUnitAttr(cir::CIRDialect::getNoUnwindAttrName());
441 addUnitAttr(cir::CIRDialect::getWillReturnAttrName());
442 }
else if (targetDecl->
hasAttr<PureAttr>()) {
443 setMemoryEffects(cir::MemoryEffectsAttr::readOnly(&
getMLIRContext()));
444 addUnitAttr(cir::CIRDialect::getNoUnwindAttrName());
446 addUnitAttr(cir::CIRDialect::getWillReturnAttrName());
447 }
else if (targetDecl->
hasAttr<NoAliasAttr>()) {
449 cir::MemoryEffectsAttr::inaccessibleOrArgMemOnly(&
getMLIRContext()));
450 addUnitAttr(cir::CIRDialect::getNoUnwindAttrName());
455 if (
const auto *restrictAttr = targetDecl->
getAttr<RestrictAttr>();
456 restrictAttr && restrictAttr->getDeallocator() ==
nullptr)
457 retAttrs.set(mlir::LLVM::LLVMDialect::getNoAliasAttrName(),
460 if (targetDecl->
hasAttr<ReturnsNonNullAttr>() &&
461 !codeGenOpts.NullPointerIsValid)
462 retAttrs.set(mlir::LLVM::LLVMDialect::getNonNullAttrName(),
464 if (targetDecl->
hasAttr<AnyX86NoCallerSavedRegistersAttr>())
465 addUnitAttr(cir::CIRDialect::getNoCallerSavedRegsAttrName());
468 if (targetDecl->
hasAttr<LeafAttr>())
469 addUnitAttr(cir::CIRDialect::getNoCallbackAttrName());
473 if (
auto *allocSizeAttr = targetDecl->
getAttr<AllocSizeAttr>()) {
474 unsigned size = allocSizeAttr->getElemSizeParam().getLLVMIndex();
476 if (allocSizeAttr->getNumElemsParam().isValid()) {
477 unsigned numElts = allocSizeAttr->getNumElemsParam().getLLVMIndex();
478 attrs.set(cir::CIRDialect::getAllocSizeAttrName(),
479 builder.getDenseI32ArrayAttr(
480 {static_cast<int>(size), static_cast<int>(numElts)}));
482 attrs.set(cir::CIRDialect::getAllocSizeAttrName(),
483 builder.getDenseI32ArrayAttr({static_cast<int>(size)}));
491 if (langOpts.OffloadUniformBlock)
492 addUnitAttr(cir::CIRDialect::getUniformWorkGroupSizeAttrName());
496 if (
auto *modularFormat = targetDecl->
getAttr<ModularFormatAttr>()) {
498 StringRef
type =
format->getType()->getName();
499 std::string formatIdx = std::to_string(
format->getFormatIdx());
500 std::string firstArg = std::to_string(
format->getFirstArg());
502 type, formatIdx, firstArg,
503 modularFormat->getModularImplFn()->getName(),
504 modularFormat->getImplName()};
505 llvm::append_range(args, modularFormat->aspects());
506 attrs.set(cir::CIRDialect::getModularFormatAttrName(),
507 builder.getStringAttr(llvm::join(args,
",")));
513 bool hasOptNoneAttr = targetDecl && targetDecl->
hasAttr<OptimizeNoneAttr>();
525 if (targetDecl->
hasAttr<ZeroCallUsedRegsAttr>()) {
528 targetDecl->
getAttr<ZeroCallUsedRegsAttr>()->getZeroCallUsedRegs();
530 cir::CIRDialect::getZeroCallUsedRegsAttrName(),
531 mlir::StringAttr::get(
533 ZeroCallUsedRegsAttr::ConvertZeroCallUsedRegsKindToStr(
kind)));
536 if (targetDecl->
hasAttr<NoConvergentAttr>())
537 attrs.erase(cir::CIRDialect::getConvergentAttrName());
542 if (!attrOnCallSite) {
546 static const llvm::StringSet<> returnsTwiceFn{
547 "_setjmpex",
"setjmp",
"_setjmp",
"vfork",
548 "sigsetjmp",
"__sigsetjmp",
"savectx",
"getcontext"};
549 if (returnsTwiceFn.contains(name))
550 addUnitAttr(cir::CIRDialect::getReturnsTwiceAttrName());
552 llvm::StringMap<std::string> cpuAndFeatures;
553 if (getCPUAndFeaturesAttributes(targetGlobalDecl, cpuAndFeatures)) {
554 for (
const auto &[key, val] : cpuAndFeatures)
555 attrs.set(key, builder.getStringAttr(val));
565 constructFunctionReturnAttributes(info, targetDecl, isThunk, retAttrs);
566 constructFunctionArgumentAttributes(info, targetGlobalDecl, isThunk,
567 attrOnCallSite, argAttrs);
570bool CIRGenModule::hasStrictReturn(
QualType retTy,
const Decl *targetDecl) {
576 if (
getLangOpts().Sanitize.has(SanitizerKind::Memory))
583 if (
const FunctionDecl *func = dyn_cast<FunctionDecl>(targetDecl)) {
584 if (func->isExternC())
586 }
else if (
const VarDecl *var = dyn_cast<VarDecl>(targetDecl)) {
588 if (var->isExternC())
601bool CIRGenModule::mayDropFunctionReturn(
const ASTContext &context,
605 if (
const RecordType *recTy =
607 if (
const auto *record = dyn_cast<CXXRecordDecl>(recTy->getDecl()))
608 return record->hasTrivialDestructor();
635 mlir::cast<cir::VectorType>(ty).getBoolStorageWidth() % 8)
660 if (
const MatrixType *Matrix = dyn_cast<MatrixType>(clangTy))
669void CIRGenModule::constructFunctionReturnAttributes(
671 mlir::NamedAttrList &retAttrs) {
673 QualType retTy =
info.getReturnType();
674 const cir::ABIArgInfo retInfo =
info.getReturnInfo();
677 if (codeGenOpts.EnableNoundefAttrs && hasStrictReturn(retTy, targetDecl) &&
680 retAttrs.set(mlir::LLVM::LLVMDialect::getNoUndefAttrName(),
684 if (llvm::FPClassTest mask =
686 retAttrs.set(mlir::LLVM::LLVMDialect::getNoFPClassAttrName(),
687 builder.getI64IntegerAttr(mask));
693 if (
const auto *refTy = retTy->
getAs<ReferenceType>()) {
694 QualType pointeeTy = refTy->getPointeeType();
696 retAttrs.set(mlir::LLVM::LLVMDialect::getDereferenceableAttrName(),
697 builder.getI64IntegerAttr(
700 if (
getTypes().getTargetAddressSpace(pointeeTy) == 0 &&
701 !codeGenOpts.NullPointerIsValid)
702 retAttrs.set(mlir::LLVM::LLVMDialect::getNonNullAttrName(),
706 retAttrs.set(mlir::LLVM::LLVMDialect::getAlignAttrName(),
707 builder.getI64IntegerAttr(
713void CIRGenModule::constructFunctionArgumentAttributes(
715 bool attrOnCallSite, llvm::MutableArrayRef<mlir::NamedAttrList> argAttrs) {
721 if (
info.isInstanceMethod() && !isThunk) {
722 QualType thisPtrTy =
info.arguments()[0];
728 if (!codeGenOpts.NullPointerIsValid &&
729 getTypes().getTargetAddressSpace(thisPtrTy) == 0) {
730 argAttrs[0].set(mlir::LLVM::LLVMDialect::getDereferenceableAttrName(),
731 builder.getI64IntegerAttr(
733 argAttrs[0].set(mlir::LLVM::LLVMDialect::getNonNullAttrName(),
740 mlir::LLVM::LLVMDialect::getDereferenceableOrNullAttrName(),
741 builder.getI64IntegerAttr(
bytes));
745 mlir::LLVM::LLVMDialect::getAlignAttrName(),
746 builder.getI64IntegerAttr(
756 const auto *dd = dyn_cast_if_present<CXXDestructorDecl>(targetDecl);
757 if (dd && codeGenOpts.StrictLifetimes &&
760 const CXXRecordDecl *classDecl = dd->getParent();
761 uint64_t dataSize = astContext.getASTRecordLayout(classDecl)
768 argAttrs[0].set(mlir::LLVM::LLVMDialect::getDeadOnReturnAttrName(),
769 builder.getI64IntegerAttr(dataSize));
780 const auto *fd = dyn_cast_or_null<FunctionDecl>(targetDecl);
785 SmallVector<const ParmVarDecl *> parmDecls;
786 parmDecls.reserve(argAttrs.size());
788 if (
info.isInstanceMethod())
789 parmDecls.push_back(
nullptr);
790 parmDecls.insert(parmDecls.end(), fd->param_begin(), fd->param_end());
792 parmDecls.resize(argAttrs.size(),
nullptr);
794 for (
const auto &[argAttrList, argCanType, pvd] :
795 llvm::zip_equal(argAttrs,
info.arguments(), parmDecls)) {
797 QualType argType = argCanType;
800 if (codeGenOpts.EnableNoundefAttrs &&
802 argAttrList.set(mlir::LLVM::LLVMDialect::getNoUndefAttrName(),
810 if (
const auto *refTy = argType->
getAs<ReferenceType>()) {
813 argAttrList.set(mlir::LLVM::LLVMDialect::getDereferenceableAttrName(),
814 builder.getI64IntegerAttr(
816 if (
getTypes().getTargetAddressSpace(pointeeTy) == 0 &&
817 !codeGenOpts.NullPointerIsValid)
818 argAttrList.set(mlir::LLVM::LLVMDialect::getNonNullAttrName(),
822 mlir::LLVM::LLVMDialect::getAlignAttrName(),
823 builder.getI64IntegerAttr(
828 if (llvm::FPClassTest mask =
830 argAttrList.set(mlir::LLVM::LLVMDialect::getNoFPClassAttrName(),
831 builder.getI64IntegerAttr(mask));
835 if (!attrOnCallSite && pvd && pvd->getType()->isPointerType() &&
836 pvd->getType().isRestrictQualified() && !fd->getBuiltinID())
837 argAttrList.set(mlir::LLVM::LLVMDialect::getNoAliasAttrName(),
842 if (pvd && argType->
isAnyPointerType() && !codeGenOpts.NullPointerIsValid) {
843 unsigned srcIdx = pvd->getFunctionScopeIndex();
844 if (pvd->hasAttr<NonNullAttr>() ||
845 (fd->getAttr<NonNullAttr>() &&
846 fd->getAttr<NonNullAttr>()->isNonNull(srcIdx)))
847 argAttrList.set(mlir::LLVM::LLVMDialect::getNonNullAttrName(),
860 if (!fpt->hasExtParameterInfos()) {
861 prefix.append(fpt->param_type_begin(), fpt->param_type_end());
868 prefix.reserve(prefix.size() + fpt->getNumParams());
870 fpt->getExtParameterInfos();
871 assert(extInfos.size() == fpt->getNumParams());
872 for (
auto [paramType, extInfo] : llvm::zip_equal(
873 llvm::make_range(fpt->param_type_begin(), fpt->param_type_end()),
875 prefix.push_back(paramType);
876 if (extInfo.hasPassObjectSize())
888 bool passParams =
true;
890 if (
auto *cd = dyn_cast<CXXConstructorDecl>(md)) {
893 if (
auto inherited = cd->getInheritedConstructor())
904 theCXXABI.buildStructorSignature(gd, argTypes);
908 (passParams && md->isVariadic() ?
RequiredArgs(argTypes.size())
911 CanQualType resultType = theCXXABI.hasThisReturn(gd) ? argTypes.front()
912 : theCXXABI.hasMostDerivedReturn(gd)
913 ? astContext.VoidPtrTy
916 assert(!theCXXABI.hasThisReturn(gd) &&
917 "Please send PR with a test and remove this");
923 fpt->getExtInfo(), required);
939 cgm.errorNYI(
"deriveThisType: no record decl");
962 fpt->getExtInfo(), required);
976 if (
type->isReferenceType()) {
982 "emitDelegateCallArg: ObjCAutoRefCount");
991 if (
type->isRecordType() &&
992 type->castAsRecordDecl()->isParamDestroyedInCallee() &&
995 "emitDelegateCallArg: callee-destructed param");
1006 if (
const auto *proto = dyn_cast<FunctionProtoType>(fnType)) {
1012 if (proto->isVariadic())
1016 cgm.
errorNYI(
"call to function without a prototype");
1019 for (
const CallArg &arg : args)
1037 unsigned extraPrefixArgs,
unsigned extraSuffixArgs,
bool passProtoArgs) {
1041 for (
const auto &arg : args)
1042 argTypes.push_back(astContext.getCanonicalParamType(arg.ty));
1045 unsigned totalPrefixArgs = 1 + extraPrefixArgs;
1050 fpt, totalPrefixArgs + extraSuffixArgs)
1054 if (theCXXABI.hasThisReturn(gd))
1056 "arrangeCXXConstructorCall: hasThisReturn");
1057 if (theCXXABI.hasMostDerivedReturn(gd))
1059 "arrangeCXXConstructorCall: hasMostDerivedReturn");
1066 fpt->getExtInfo(), required);
1077 assert(numPrefixArgs + 1 <= args.size() &&
1078 "Emitting a call with less args than the required prefix?");
1082 for (
const CallArg &arg : args)
1083 argTypes.push_back(astContext.getCanonicalParamType(arg.ty));
1088 true, argTypes, proto->
getExtInfo(), required);
1101 for (
const CallArg &arg : args)
1102 argTypes.push_back(astContext.getCanonicalParamType(arg.ty));
1113 if (fd->
hasAttr<CUDAGlobalAttr>()) {
1142 auto *thisType = theCXXABI.getThisArgumentTypeForMethod(md);
1164 return ::arrangeCIRFunctionInfo(
1165 *
this,
true, argTypes,
1173 if (
const auto *md = dyn_cast<CXXMethodDecl>(fd))
1174 if (md->isInstance())
1209 if (!ac.
getDecl() || !(
sanOpts.has(SanitizerKind::NonnullAttribute) ||
1210 sanOpts.has(SanitizerKind::NullabilityArg)))
1212 cgm.errorNYI(
"non-null arg check is NYI");
1216 CIRGenFunction &cgf, mlir::Location callLoc, cir::FuncType indirectFuncTy,
1217 mlir::Value indirectFuncVal, cir::FuncOp directFuncOp,
1219 const mlir::NamedAttrList &attrs,
1221 const mlir::NamedAttrList &retAttrs, cir::CallingConv callingConv) {
1226 assert(builder.getInsertionBlock() &&
"expected valid basic block");
1229 if (indirectFuncTy) {
1231 cirCallArgs, attrs, argAttrs, retAttrs,
1234 op = builder.
createCallOp(callLoc, directFuncOp, cirCallArgs, attrs,
1235 argAttrs, retAttrs, callingConv);
1245 return ::arrangeCIRFunctionInfo(*
this,
false, argTypes,
1261 cir::CIRCallOpInterface *callOp,
1265 mlir::Location loc =
getLoc(clangLoc);
1271 if (
const FunctionDecl *fd = dyn_cast_or_null<FunctionDecl>(targetDecl)) {
1278 if ((targetDecl->
hasAttr<AlwaysInlineAttr>() &&
1279 (targetDecl->
hasAttr<TargetAttr>() ||
1283 targetDecl->
hasAttr<TargetAttr>())))
1288 const FunctionDecl *calleeDecl = dyn_cast_or_null<FunctionDecl>(targetDecl);
1293 for (
auto [argNo, arg, canQualArgType] :
1294 llvm::enumerate(args, funcInfo.
argTypes())) {
1300 if (!mlir::isa<cir::RecordType>(argType) &&
1301 !mlir::isa<cir::ComplexType>(argType)) {
1303 if (arg.isAggregate())
1304 cgm.errorNYI(loc,
"emitCall: aggregate call argument");
1305 v = arg.getKnownRValue().getValue();
1308 if (argType != v.getType() && mlir::isa<cir::IntType>(v.getType()))
1309 cgm.errorNYI(loc,
"emitCall: widening integer call argument");
1313 if (argType != v.getType()) {
1314 auto argPtrTy = mlir::dyn_cast<cir::PointerType>(argType);
1315 auto vPtrTy = mlir::dyn_cast<cir::PointerType>(v.getType());
1316 if (argPtrTy && vPtrTy &&
1317 argPtrTy.getPointee() == vPtrTy.getPointee() &&
1318 argPtrTy.getAddrSpace() != vPtrTy.getAddrSpace()) {
1328 cirCallArgs[argNo] = v;
1331 if (!arg.isAggregate()) {
1333 arg.copyInto(*
this, src, loc);
1335 src = arg.hasLValue() ? arg.getKnownLValue().getAddress()
1336 : arg.getKnownRValue().getAggregateAddress();
1343 mlir::Location argLoc = loc;
1356 if (srcTy != argType) {
1357 cgm.errorNYI(loc,
"emitCall: source type does not match argument type");
1373 cirCallArgs[argNo] = builder.createLoad(argLoc, src);
1382 mlir::NamedAttrList attrs;
1383 std::vector<mlir::NamedAttrList> argAttrs(funcInfo.
arguments().size());
1384 mlir::NamedAttrList retAttrs;
1386 if (
auto calleeFuncOp = dyn_cast<cir::FuncOp>(calleePtr))
1387 funcName = calleeFuncOp.getName();
1390 cir::CallingConv callingConv;
1392 attrs, argAttrs, retAttrs, callingConv,
1398 if (callingConv == cir::CallingConv::SpirKernel ||
1399 callingConv == cir::CallingConv::AMDGPUKernel ||
1400 callingConv == cir::CallingConv::PTXKernel)
1401 cgm.errorNYI(loc,
"emitCall: call to kernel function");
1403 auto resolvedFuncOpFromGlobal = [&](mlir::Operation *op) -> cir::FuncOp {
1404 if (
auto fnOp = dyn_cast<cir::FuncOp>(op))
1406 if (
auto getGlobalOp = dyn_cast<cir::GetGlobalOp>(op)) {
1411 mlir::Operation *globalOp =
cgm.getGlobalValue(getGlobalOp.getName());
1412 assert(globalOp &&
"undefined global function");
1418 cir::FuncType indirectFuncTy;
1419 mlir::Value indirectFuncVal;
1420 cir::FuncOp directFuncOp;
1429 if (cir::FuncOp candidate = resolvedFuncOpFromGlobal(calleePtr)) {
1430 if (candidate.getFunctionType() == cirFuncTy) {
1431 directFuncOp = candidate;
1433 mlir::Value addr = cir::GetGlobalOp::create(
1434 builder, loc, cir::PointerType::get(candidate.getFunctionType()),
1435 candidate.getSymName());
1436 indirectFuncTy = cirFuncTy;
1438 builder.createBitcast(addr, cir::PointerType::get(cirFuncTy));
1441 [[maybe_unused]] mlir::ValueTypeRange<mlir::ResultRange> resultTypes =
1442 calleePtr->getResultTypes();
1443 [[maybe_unused]]
auto funcPtrTy =
1444 mlir::dyn_cast<cir::PointerType>(resultTypes.front());
1445 assert(funcPtrTy && mlir::isa<cir::FuncType>(funcPtrTy.getPointee()) &&
1446 "expected pointer to function");
1448 indirectFuncTy = cirFuncTy;
1449 indirectFuncVal = calleePtr->getResult(0);
1456 bool cannotThrow = attrs.getNamed(
"nothrow").has_value();
1459 mlir::Location callLoc = loc;
1461 *
this, loc, indirectFuncTy, indirectFuncVal, directFuncOp, cirCallArgs,
1462 isInvoke, attrs, argAttrs, retAttrs, callingConv);
1469 bool needSrcLoc = calleeDecl->
hasAttr<ErrorAttr>();
1470 if (!needSrcLoc &&
cgm.getCodeGenOpts().ShowInliningChain)
1472 calleeDecl->
hasAttr<AlwaysInlineAttr>() ||
1477 cir::CIRDialect::getSrcLocAttrName(),
1486 theCall.setInlineKind(cir::InlineKind::NoInline);
1488 !
cgm.getTargetCIRGenInfo().wouldInliningViolateFunctionCallABI(
1489 callerDecl, calleeDecl))
1490 theCall.setInlineKind(cir::InlineKind::AlwaysInline);
1496 if (triple.isPPC() || triple.isMIPS()) {
1498 "musttail call target legality checks");
1508 cgm.errorUnsupported(
mustTailCall,
"tail call skipping over cleanups");
1516 diag::err_musttail_noexcept_mismatch);
1528 auto *cleanupScope = dyn_cast<EHCleanupScope>(&*it);
1529 if (!cleanupScope ||
1530 !cleanupScope->getCleanup()->isRedundantBeforeReturn()) {
1531 cgm.errorUnsupported(
mustTailCall,
"tail call skipping over cleanups");
1536 theCall->setAttr(cir::CIRDialect::getMustTailAttrName(),
1537 builder.getUnitAttr());
1540 cir::ReturnOp::create(builder, loc);
1542 cir::ReturnOp::create(builder, loc, theCall->getResult(0));
1547 builder.createBlock(builder.getBlock()->getParent());
1563 mlir::ResultRange results = theCall->getOpResults();
1564 assert(results.size() <= 1 &&
"multiple returns from a call");
1571 mlir::ResultRange results = theCall->getOpResults();
1572 assert(results.size() == 1 &&
"unexpected number of returns");
1576 if (results[0].
getType() != retCIRTy)
1577 cgm.errorNYI(loc,
"bitcast on function return value");
1579 mlir::Region *region = builder.getBlock()->getParent();
1580 if (region != theCall->getParentRegion())
1581 cgm.errorNYI(loc,
"function calls with cleanup");
1586 mlir::ResultRange results = theCall->getOpResults();
1587 assert(!results.empty() &&
1588 "Expected at least one result for complex rvalue");
1592 llvm_unreachable(
"Invalid evaluation kind");
1596 mlir::Location loc)
const {
1598 if (!hasLV &&
rv.isScalar())
1600 else if (!hasLV &&
rv.isComplex())
1610 mlir::NamedAttrList attrs) {
1615 cir::CallOp call = builder.createCallOp(loc, callee, args);
1616 assert(call->getNumResults() <= 1 &&
1617 "runtime functions have at most 1 result");
1620 call->setAttrs(attrs);
1622 if (call->getNumResults() == 0)
1625 return call->getResult(0);
1631 "reference binding to unmaterialized r-value!");
1647 bool destroyedInCallee =
true;
1649 destroyedInCallee = rd->hasNonTrivialDestructor();
1651 if (destroyedInCallee)
1656 args.
add(rv, argType);
1658 if (destroyedInCallee &&
getLangOpts().Exceptions)
1660 "callee-destructed param with exceptions");
1675QualType CIRGenFunction::getVarArgType(
const Expr *arg) {
1680 return arg->getType();
1683 cgm.
errorNYI(arg->getSourceRange(),
"getVarArgType: NYI for Windows target");
1684 return arg->getType();
1701 llvm::iterator_range<clang::CallExpr::const_arg_iterator> argRange,
1708 bool isVariadic =
false;
1713 isVariadic = fpt->isVariadic();
1715 argTypes.assign(fpt->param_type_begin() + paramsToSkip,
1716 fpt->param_type_end());
1720 for (
const clang::Expr *a : llvm::drop_begin(argRange, argTypes.size()))
1721 argTypes.push_back(isVariadic ? getVarArgType(a) : a->getType());
1722 assert(argTypes.size() == (
size_t)(argRange.end() - argRange.begin()));
1732 auto maybeEmitImplicitObjectSize = [&](
size_t i,
const Expr *arg,
1741 assert(emittedArg.getValue() &&
"We emitted nothing for the arg?");
1744 emittedArg.getValue(), ps->isDynamic());
1750 std::iter_swap(args.rbegin(), std::next(args.rbegin()));
1754 size_t callArgsStart = args.size();
1755 for (
size_t i = 0; i != argTypes.size(); ++i) {
1756 size_t idx = leftToRight ? i : argTypes.size() - i - 1;
1758 size_t initialArgSize = args.size();
1764 assert(initialArgSize + 1 == args.size() &&
1765 "The code below depends on only adding one arg per emitCallArg");
1766 (void)initialArgSize;
1770 if (!args.back().hasLValue()) {
1771 RValue rvArg = args.back().getKnownRValue();
1773 maybeEmitImplicitObjectSize(idx, *currentArg, rvArg);
1780 std::reverse(args.begin() + callArgsStart, args.end());
static StringRef bytes(const std::vector< T, Allocator > &v)
static void setCUDAKernelCallingConvention(CanQualType &funcTy, CIRGenModule &cgm, const FunctionDecl *fd)
Set calling convention for CUDA/HIP kernel.
static void addTrivialDefaultFunctionAttributes(mlir::MLIRContext *mlirCtx, StringRef name, bool hasOptNoneAttr, const CodeGenOptions &codeGenOpts, const LangOptions &langOpts, bool attrOnCallSite, mlir::NamedAttrList &attrs)
Add default attributes to a function, which have merge semantics under -mlink-builtin-bitcode and sho...
static void addNoBuiltinAttributes(mlir::MLIRContext &ctx, mlir::NamedAttrList &attrs, const LangOptions &langOpts, const NoBuiltinAttr *nba=nullptr)
static bool determineNoUndef(QualType clangTy, CIRGenTypes &types, const cir::CIRDataLayout &layout, const cir::ABIArgInfo &argInfo)
static void addDenormalModeAttrs(llvm::DenormalMode fpDenormalMode, llvm::DenormalMode fp32DenormalMode, mlir::NamedAttrList &attrs)
Add denormal-fp-math and denormal-fp-math-f32 as appropriate for the requested denormal behavior,...
static void addMergeableDefaultFunctionAttributes(const CodeGenOptions &codeGenOpts, mlir::NamedAttrList &attrs)
Add default attributes to a function, which have merge semantics under -mlink-builtin-bitcode and sho...
static void appendParameterTypes(const CIRGenTypes &cgt, SmallVectorImpl< CanQualType > &prefix, CanQual< FunctionProtoType > fpt)
Adds the formal parameters in FPT to the given prefix.
static void addAttributesFromFunctionProtoType(CIRGenBuilderTy &builder, mlir::NamedAttrList &attrs, const FunctionProtoType *fpt)
static llvm::StringLiteral getZeroCallUsedRegsKindStr(llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind k)
static const CIRGenFunctionInfo & arrangeFreeFunctionLikeCall(CIRGenTypes &cgt, CIRGenModule &cgm, const CallArgList &args, const FunctionType *fnType)
static cir::CIRCallOpInterface emitCallLikeOp(CIRGenFunction &cgf, mlir::Location callLoc, cir::FuncType indirectFuncTy, mlir::Value indirectFuncVal, cir::FuncOp directFuncOp, const SmallVectorImpl< mlir::Value > &cirCallArgs, bool isInvoke, const mlir::NamedAttrList &attrs, llvm::ArrayRef< mlir::NamedAttrList > argAttrs, const mlir::NamedAttrList &retAttrs, cir::CallingConv callingConv)
static const CIRGenFunctionInfo & arrangeCIRFunctionInfo(CIRGenTypes &cgt, bool instanceMethod, SmallVectorImpl< CanQualType > &prefix, CanQual< FunctionProtoType > fpt)
Arrange the CIR function layout for a value of the given function type, on top of any implicit parame...
static StringRef getTriple(const Command &Job)
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
static bool isVirtualCall(const CallExpr *CE)
bool isIndirectAliased() const
static ABIArgInfo getDirect(mlir::Type ty=nullptr)
cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee, mlir::Type returnType, mlir::ValueRange operands, llvm::ArrayRef< mlir::NamedAttribute > attrs={}, llvm::ArrayRef< mlir::NamedAttrList > argAttrs={}, llvm::ArrayRef< mlir::NamedAttribute > resAttrs={}, cir::CallingConv callingConv=cir::CallingConv::C)
cir::CallOp createIndirectCallOp(mlir::Location loc, mlir::Value indirectTarget, cir::FuncType funcType, mlir::ValueRange operands, llvm::ArrayRef< mlir::NamedAttribute > attrs={}, llvm::ArrayRef< mlir::NamedAttrList > argAttrs={}, llvm::ArrayRef< mlir::NamedAttribute > resAttrs={}, cir::CallingConv callingConv=cir::CallingConv::C)
bool typeSizeEqualsStoreSize(mlir::Type ty) const
Returns true if no extra padding bits are needed when storing the specified type.
CanQualType getCanonicalParamType(QualType T) const
Return the canonical parameter type corresponding to the specific potentially non-canonical one.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
CanQualType getCanonicalSizeType() const
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
const TargetInfo & getTargetInfo() const
CanQualType getCanonicalTagType(const TagDecl *TD) const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
mlir::Type getElementType() const
void setExternallyDestructed(bool destructed=true)
static AggValueSlot ignored()
Returns an aggregate value slot indicating that the aggregate value is being ignored.
virtual CIRGenCallee getVirtualFunctionPointer(CIRGenFunction &cgf, clang::GlobalDecl gd, Address thisAddr, mlir::Type ty, SourceLocation loc)=0
Build a virtual function pointer in the ABI-specific way.
Abstract information about a function or function prototype.
clang::GlobalDecl getCalleeDecl() const
const clang::FunctionProtoType * getCalleeFunctionProtoType() const
CIRGenCalleeInfo getAbstractInfo() const
clang::GlobalDecl getVirtualMethodDecl() const
CIRGenCallee prepareConcreteCallee(CIRGenFunction &cgf) const
If this is a delayed callee computation of some sort, prepare a concrete callee.
Address getThisAddress() const
cir::FuncType getVirtualFunctionType() const
const clang::CallExpr * getVirtualCallExpr() const
mlir::Operation * getFunctionPointer() const
CanQualType getReturnType() const
llvm::MutableArrayRef< CanQualType > argTypes()
static CIRGenFunctionInfo * create(cir::CallingConv cirCC, FunctionType::ExtInfo info, bool instanceMethod, CanQualType resultType, llvm::ArrayRef< CanQualType > argTypes, RequiredArgs required)
bool isInstanceMethod() const
llvm::ArrayRef< CanQualType > arguments() const
const_arg_iterator argTypesBegin() const
An abstract representation of regular/ObjC call/message targets.
bool hasFunctionDecl() const
unsigned getNumParams() const
const clang::Decl * getDecl() const
const clang::ParmVarDecl * getParamDecl(unsigned I) const
mlir::Type convertType(clang::QualType t)
static cir::TypeEvaluationKind getEvaluationKind(clang::QualType type)
Return the cir::TypeEvaluationKind of QualType type.
RValue convertTempToRValue(Address addr, clang::QualType type, clang::SourceLocation loc)
Given the address of a temporary variable, produce an r-value of its type.
EHScopeStack::stable_iterator prologueCleanupDepth
The cleanup depth enclosing all the cleanups associated with the parameters.
CIRGenTypes & getTypes() const
const clang::LangOptions & getLangOpts() const
const TargetInfo & getTarget() const
LValue emitLValue(const clang::Expr *e)
Emit code to compute a designator that specifies the location of the expression.
const clang::Decl * curFuncDecl
Address getAddrOfLocalVar(const clang::VarDecl *vd)
Return the address of a local variable.
void emitAggregateCopy(LValue dest, LValue src, QualType eltTy, AggValueSlot::Overlap_t mayOverlap, bool isVolatile=false)
Emit an aggregate copy.
cir::TryOp ehSpecTryOp
The cir.try wrapping a function whose exception specification has to be enforced.
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
CodeGenUtils::EvaluationOrder EvaluationOrder
void emitCallArgs(CallArgList &args, PrototypeWrapper prototype, llvm::iterator_range< clang::CallExpr::const_arg_iterator > argRange, AbstractCallee callee=AbstractCallee(), unsigned paramsToSkip=0, EvaluationOrder order=EvaluationOrder::Default)
void emitAggregateStore(mlir::Value value, Address dest)
mlir::Value performAddrSpaceCast(mlir::Value v, mlir::Type destTy) const
RValue emitReferenceBindingToExpr(const Expr *e)
Emits a reference binding to the passed in expression.
mlir::Value evaluateOrEmitBuiltinObjectSize(const clang::Expr *e, unsigned type, cir::IntType resType, mlir::Value emittedE, bool isDynamic)
void checkTargetFeatures(const clang::CallExpr *e, const clang::FunctionDecl *targetDecl)
Emit a diagnostic if the target features required by targetDecl are not available in the calling func...
EHScopeStack ehStack
Tracks function scope overall cleanup handling.
AggValueSlot createAggTemp(QualType ty, mlir::Location loc, const Twine &name="tmp", Address *alloca=nullptr)
Create a temporary memory object for the given aggregate type.
clang::SanitizerSet sanOpts
Sanitizers enabled for this function.
RValue getUndefRValue(clang::QualType ty)
Get an appropriate 'undef' rvalue for the given type.
Address returnValue
The temporary alloca to hold the return value.
static bool hasAggregateEvaluationKind(clang::QualType type)
RValue emitAnyExprToTemp(const clang::Expr *e)
Similarly to emitAnyExpr(), however, the result will always be accessible even if no aggregate locati...
const CallExpr * mustTailCall
void emitStoreOfComplex(mlir::Location loc, mlir::Value v, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
std::string getCounterAggTmpAsString()
void emitCallArg(CallArgList &args, const clang::Expr *e, clang::QualType argType)
const clang::Decl * curCodeDecl
This is the inner-most code context, which includes blocks.
CIRGenBuilderTy & getBuilder()
void emitNonNullArgCheck(RValue rv, QualType argType, SourceLocation argLoc, AbstractCallee ac, unsigned paramNum)
Create a check for a function parameter that may potentially be declared as non-null.
mlir::Value emitRuntimeCall(mlir::Location loc, cir::FuncOp callee, llvm::ArrayRef< mlir::Value > args={}, mlir::NamedAttrList attrs={})
std::optional< SourceRange > currSrcLoc
Use to track source locations across nested visitor traversals.
RValue emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, const CallArgList &args, cir::CIRCallOpInterface *callOp, bool isMustTail, SourceRange clangLoc)
LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)
bool isCatchOrCleanupRequired()
RValue emitAnyExpr(const clang::Expr *e, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
Emit code to compute the specified expression which can have any type.
void emitDelegateCallArg(CallArgList &args, const clang::VarDecl *param, clang::SourceLocation loc)
We are performing a delegate call; that is, the current function is delegating to another one.
bool inEHSpecTerminateScope()
Whether the wrapper opened by emitStartEHSpec is a terminate scope, whose handler calls std::terminat...
clang::ASTContext & getContext() const
bool inAlwaysInlineAttributedStmt
True if the current statement has always_inline attribute.
bool inNoInlineAttributedStmt
True if the current statement has noinline attribute.
Address createMemTemp(QualType t, mlir::Location loc, const Twine &name="tmp", Address *alloca=nullptr, mlir::OpBuilder::InsertPoint ip={})
Create a temporary memory object of the given type, with appropriate alignmen and cast it to the defa...
void emitAggExpr(const clang::Expr *e, AggValueSlot slot)
This class organizes the cross-function state that is used while generating CIR code.
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
clang::ASTContext & getASTContext() const
void addDefaultFunctionAttributes(StringRef name, bool hasOptNoneAttr, bool attrOnCallSite, mlir::NamedAttrList &attrs)
Helper function for constructAttributeList/others.
CIRGenBuilderTy & getBuilder()
const cir::CIRDataLayout & getDataLayout() const
CharUnits getMinimumObjectSize(QualType ty)
Returns the minimum object size for an object of the given type.
static std::optional< cir::FramePointerKind > getFramePointerKind(CodeGenOptions::FramePointerKind kind)
Returns the frame pointer kind to record on functions and on the module, or std::nullopt when kind is...
const clang::CodeGenOptions & getCodeGenOpts() const
const clang::LangOptions & getLangOpts() const
const TargetCIRGenInfo & getTargetCIRGenInfo()
mlir::MLIRContext & getMLIRContext()
CIRGenCXXABI & getCXXABI() const
clang::CharUnits getNaturalPointeeTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo=nullptr)
void constructAttributeList(llvm::StringRef name, const CIRGenFunctionInfo &info, CIRGenCalleeInfo calleeInfo, mlir::NamedAttrList &attrs, llvm::MutableArrayRef< mlir::NamedAttrList > argAttrs, mlir::NamedAttrList &retAttrs, cir::CallingConv &callingConv, bool attrOnCallSite, bool isThunk)
Get the CIR attributes and calling convention to use for a particular function type.
This class organizes the cross-module state that is used while lowering AST types to CIR types.
const CIRGenFunctionInfo & arrangeGlobalDeclaration(GlobalDecl gd)
const CIRGenFunctionInfo & arrangeCXXMethodDeclaration(const clang::CXXMethodDecl *md)
C++ methods have some special rules and also have implicit parameters.
const CIRGenFunctionInfo & arrangeCXXStructorDeclaration(clang::GlobalDecl gd)
const CIRGenFunctionInfo & arrangeCIRFunctionInfo(CanQualType returnType, bool isInstanceMethod, llvm::ArrayRef< CanQualType > argTypes, FunctionType::ExtInfo info, RequiredArgs required)
const CIRGenFunctionInfo & arrangeFreeFunctionCall(const CallArgList &args, const FunctionType *fnType)
const CIRGenFunctionInfo & arrangeFreeFunctionType(CanQual< FunctionProtoType > fpt)
const CIRGenFunctionInfo & arrangeBuiltinFunctionCall(QualType resultType, const CallArgList &args)
A builtin function is a freestanding function using the default C conventions.
const CIRGenFunctionInfo & arrangeCXXConstructorCall(const CallArgList &args, const clang::CXXConstructorDecl *d, clang::CXXCtorType ctorKind, unsigned extraPrefixArgs, unsigned extraSuffixArgs, bool passProtoArgs=true)
Arrange a call to a C++ method, passing the given arguments.
const CIRGenFunctionInfo & arrangeCXXMethodType(const clang::CXXRecordDecl *rd, const clang::FunctionProtoType *ftp, const clang::CXXMethodDecl *md)
Arrange the argument and result information for a call to an unknown C++ non-static member function o...
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR 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...
clang::CanQualType deriveThisType(const clang::CXXRecordDecl *rd, const clang::CXXMethodDecl *md)
Derives the 'this' type for CIRGen purposes, i.e.
const CIRGenFunctionInfo & arrangeFunctionDeclaration(const clang::FunctionDecl *fd)
Free functions are functions that are compatible with an ordinary C function pointer type.
clang::ASTContext & getASTContext() const
const CIRGenFunctionInfo & arrangeCXXMethodCall(const CallArgList &args, const clang::FunctionProtoType *type, RequiredArgs required, unsigned numPrefixArgs)
Arrange a call to a C++ method, passing the given arguments.
mlir::Type convertType(clang::QualType type)
Convert a Clang type into a mlir::Type.
mlir::Type convertTypeForMem(clang::QualType, bool forBitField=false)
Convert type T into an mlir::Type.
void addUncopiedAggregate(LValue lvalue, clang::QualType type)
void add(RValue rvalue, clang::QualType type)
A non-stable pointer into the scope stack.
Address getAddress() const
This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(mlir::Value v)
static RValue getAggregate(Address addr, bool isVolatile=false)
Convert an Address to an RValue.
static RValue getComplex(mlir::Value v)
A class for recording the number of arguments that a function signature requires.
static RequiredArgs getFromProtoWithExtraSlots(const clang::FunctionProtoType *prototype, unsigned additional)
Compute the arguments required by the given formal prototype, given that there may be some additional...
Contains the address where the return value of a function can be stored, and whether the address is v...
virtual bool isNoProtoCallVariadic(const FunctionNoProtoType *fnType) const
Determine whether a call to an unprototyped functions under the given calling convention should use t...
virtual void setCUDAKernelCallingConvention(const clang::FunctionType *&ft) const
Represents a C++ constructor 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...
Qualifiers getMethodQualifiers() const
Represents a C++ struct/union/class.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
SourceLocation getBeginLoc() const
ConstExprIterator const_arg_iterator
Represents a canonical, potentially-qualified type.
static CanQual< Type > CreateUnsafe(QualType Other)
CanProxy< U > castAs() const
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
CanProxy< U > getAs() const
Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
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.
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
Complex values, per C99 6.2.5p11.
bool constructsVirtualBase() const
Returns true if the constructed base class is a virtual base class subobject of this declaration's cl...
bool isInAnonymousNamespace() const
This represents one expression.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
Represents a function declaration or definition.
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
StorageClass getStorageClass() const
Returns the storage class as written in the source.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
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.
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
A class which abstracts out some details necessary for making a call.
FunctionType - C99 6.7.5.3 - Function Declarators.
ExtInfo getExtInfo() const
QualType getReturnType() const
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
CXXDtorType getDtorType() const
const Decl * getDecl() const
Description of a constructor that was inherited from a base class.
ConstructorUsingShadowDecl * getShadowDecl() const
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).
bool isNoBuiltinFunc(StringRef Name) const
Is this a libc/libm function that is no longer recognized as a builtin because a -fno-builtin-* optio...
SanitizerSet Sanitize
Set of enabled sanitizers.
bool assumeFunctionsAreConvergent() const
Represents a matrix type, as defined in the Matrix Types clang extensions.
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
QualType getCanonicalType() const
LangAS getAddressSpace() const
bool isParamDestroyedInCallee() const
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.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
bool hasConstructorVariants() const
Does this ABI have different entrypoints for complete-object and base-subobject constructors?
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
bool isPackedVectorBoolType(const ASTContext &ctx) const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
CanQualType getCanonicalTypeUnqualified() const
bool isReferenceType() const
bool isScalarType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isBitIntType() const
RecordDecl * castAsRecordDecl() const
bool isMemberPointerType() const
bool isObjectType() const
Determine whether this type is an object type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
bool isAnyPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
Represents a variable declaration or definition.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
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.
bool isSized(mlir::Type ty)
Returns true if the type is a CIR sized type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
CanQual< FunctionProtoType > getFormalType(const CXXMethodDecl *MD)
Returns the canonical formal type of the given C++ method.
llvm::FPClassTest getNoFPClassTestMask(const LangOptions &LangOpts)
Returns the set of floating-point value kinds that the language options promise never reach a functio...
bool shouldEvaluateArgsLeftToRight(EvaluationOrder Order, const TargetCXXABI &ABI)
Returns true if call arguments should be emitted left-to-right, given the order the language requires...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
void info(bool Verbose, unsigned Level, const char *Fmt, Ts &&...Args)
Prints an indented note to stderr when Verbose is set.
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
CXXCtorType
C++ constructor types.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
bool isUnresolvedExceptionSpec(ExceptionSpecificationType ESpecType)
@ OK_Ordinary
An ordinary object is located at an address in memory.
@ Vector
'vector' clause, allowed on 'loop', Combined, and 'routine' directives.
@ Dtor_VectorDeleting
Vector deleting dtor.
@ Dtor_Deleting
Deleting dtor.
U cast(CodeGen::Address addr)
static bool opCallBitcastArg()
static bool opCallCIRGenFuncInfoExtParamInfo()
static bool functionUsesSEHTry()
static bool emitLifetimeMarkers()
static bool lowerAggregateLoadStore()
static bool opCallSurroundingTry()
static bool nothrowAttr()
static bool opCallReturn()
static bool opCallPaddingArgs()
static bool opCallExtParameterInfo()
static bool dataLayoutTypeAllocSize()
static bool opCallObjCMethod()
static bool opCallInAlloca()
static bool opCallCallConv()
static bool opFuncCallingConv()
static bool opCallAttrs()
static bool fakeUseCleanup()
static bool opCallFnInfoOpts()
static bool msvcCXXPersonality()
static bool opCallCIRGenFuncInfoParamInfo()
Similar to AddedStructorArgs, but only notes the number of additional arguments.
llvm::PointerUnion< const clang::FunctionProtoType *, const clang::ObjCMethodDecl * > p
RValue getRValue(CIRGenFunction &cgf, mlir::Location loc) const
void copyInto(CIRGenFunction &cgf, Address addr, mlir::Location loc) const
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.