18#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
19#include "mlir/IR/Attributes.h"
22#include "llvm/ADT/FloatingPointMode.h"
23#include "llvm/ADT/StringSet.h"
24#include "llvm/Support/TypeSize.h"
35 void *buffer =
operator new(
36 totalSizeToAlloc<CanQualType>(
argTypes.size() + 1));
40 CIRGenFunctionInfo *fi =
new (buffer) CIRGenFunctionInfo();
42 fi->callingConvention = llvm::to_underlying(cirCC);
43 fi->astCallingConvention = info.getCC();
44 fi->noReturn = info.getNoReturn();
47 fi->required = required;
54 assert((!required.allowsOptionalArgs() ||
55 required.getNumRequiredArgs() <= fi->numArgs) &&
56 "more required arguments than argument types");
58 fi->getArgTypes()[0] = resultType;
71 mlir::Type resultType =
convertType(info.getReturnType());
73 argTypes.reserve(info.getNumRequiredArgs());
75 for (
const CanQualType &argType : info.requiredArguments())
78 return cir::FuncType::get(argTypes,
79 (resultType ? resultType : builder.getVoidTy()),
105 mlir::OpBuilder::InsertionGuard guard(builder);
106 builder.setInsertionPointAfter(value.getDefiningOp());
107 builder.createStore(*
currSrcLoc, value, dest);
111 mlir::NamedAttrList &attrs,
118 attrs.set(cir::CIRDialect::getNoThrowAttrName(),
119 mlir::UnitAttr::get(builder.getContext()));
123 mlir::NamedAttrList &attrs,
125 const NoBuiltinAttr *nba =
nullptr) {
129 if (langOpts.NoBuiltin ||
130 (nba && llvm::is_contained(nba->builtinNames(),
"*"))) {
133 attrs.set(cir::CIRDialect::getNoBuiltinsAttrName(),
134 mlir::ArrayAttr::get(&ctx, {}));
138 llvm::SetVector<mlir::Attribute> nbFuncs;
139 auto addNoBuiltinAttr = [&ctx, &nbFuncs](StringRef builtinName) {
140 nbFuncs.insert(mlir::StringAttr::get(&ctx, builtinName));
149 llvm::for_each(nba->builtinNames(), addNoBuiltinAttr);
151 if (!nbFuncs.empty())
152 attrs.set(cir::CIRDialect::getNoBuiltinsAttrName(),
153 mlir::ArrayAttr::get(&ctx, nbFuncs.getArrayRef()));
160 llvm::DenormalMode fp32DenormalMode,
161 mlir::NamedAttrList &attrs) {
173 mlir::NamedAttrList &attrs) {
178static llvm::StringLiteral
181 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Skip:
182 llvm_unreachable(
"No string value, shouldn't be able to get here");
183 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPRArg:
184 return "used-gpr-arg";
185 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPR:
187 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedArg:
189 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Used:
191 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPRArg:
192 return "all-gpr-arg";
193 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPR:
195 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllArg:
197 case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::All:
201 llvm_unreachable(
"Unknown kind?");
208 mlir::MLIRContext *mlirCtx, StringRef name,
bool hasOptNoneAttr,
210 bool attrOnCallSite, mlir::NamedAttrList &attrs) {
213 if (!hasOptNoneAttr) {
214 if (codeGenOpts.OptimizeSize)
215 attrs.set(cir::CIRDialect::getOptimizeForSizeAttrName(),
216 mlir::UnitAttr::get(mlirCtx));
217 if (codeGenOpts.OptimizeSize == 2)
218 attrs.set(cir::CIRDialect::getMinSizeAttrName(),
219 mlir::UnitAttr::get(mlirCtx));
225 if (attrOnCallSite) {
228 attrs.set(cir::CIRDialect::getNoBuiltinAttrName(),
229 mlir::UnitAttr::get(mlirCtx));
232 attrs.set(cir::CIRDialect::getTrapFuncNameAttrName(),
233 mlir::StringAttr::get(mlirCtx, codeGenOpts.
TrapFuncName));
248 if (codeGenOpts.getZeroCallUsedRegs() ==
249 llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Skip)
250 attrs.erase(cir::CIRDialect::getZeroCallUsedRegsAttrName());
252 attrs.set(cir::CIRDialect::getZeroCallUsedRegsAttrName(),
253 mlir::StringAttr::get(mlirCtx,
255 codeGenOpts.getZeroCallUsedRegs())));
264 attrs.set(cir::CIRDialect::getConvergentAttrName(),
265 mlir::UnitAttr::get(mlirCtx));
271 if (codeGenOpts.SaveRegParams && !attrOnCallSite)
272 attrs.set(cir::CIRDialect::getSaveRegParamsAttrName(),
273 mlir::UnitAttr::get(mlirCtx));
282 [mlirCtx](llvm::StringRef arg) {
283 auto [var, value] = arg.split(
'=');
286 ? cast<mlir::Attribute>(mlir::UnitAttr::get(mlirCtx))
287 : cast<mlir::Attribute>(mlir::StringAttr::get(mlirCtx, value));
288 return mlir::NamedAttribute(var, valueAttr);
291 if (!defaultFuncAttrs.empty())
292 attrs.set(cir::CIRDialect::getDefaultFuncAttrsAttrName(),
293 mlir::DictionaryAttr::get(mlirCtx, defaultFuncAttrs));
305 mlir::NamedAttrList &attrs) {
308 codeGenOpts, langOpts, attrOnCallSite,
311 if (!attrOnCallSite) {
324 mlir::NamedAttrList &retAttrs, cir::CallingConv &callingConv,
325 cir::SideEffect &sideEffect,
bool attrOnCallSite,
bool isThunk) {
326 callingConv = info.getCallingConvention();
327 sideEffect = cir::SideEffect::All;
329 auto addUnitAttr = [&](llvm::StringRef name) {
333 if (info.isNoReturn())
334 addUnitAttr(cir::CIRDialect::getNoReturnAttrName());
346 const NoBuiltinAttr *nba =
nullptr;
352 if (targetDecl->
hasAttr<NoThrowAttr>())
353 addUnitAttr(cir::CIRDialect::getNoThrowAttrName());
358 if (targetDecl->
hasAttr<NoReturnAttr>())
359 addUnitAttr(cir::CIRDialect::getNoReturnAttrName());
360 if (targetDecl->
hasAttr<ReturnsTwiceAttr>())
361 addUnitAttr(cir::CIRDialect::getReturnsTwiceAttrName());
362 if (targetDecl->
hasAttr<ColdAttr>())
363 addUnitAttr(cir::CIRDialect::getColdAttrName());
364 if (targetDecl->
hasAttr<HotAttr>())
365 addUnitAttr(cir::CIRDialect::getHotAttrName());
366 if (targetDecl->
hasAttr<NoDuplicateAttr>())
367 addUnitAttr(cir::CIRDialect::getNoDuplicatesAttrName());
368 if (targetDecl->
hasAttr<ConvergentAttr>())
369 addUnitAttr(cir::CIRDialect::getConvergentAttrName());
371 if (
const FunctionDecl *func = dyn_cast<FunctionDecl>(targetDecl)) {
385 if (func->isNoReturn())
386 addUnitAttr(cir::CIRDialect::getNoReturnAttrName());
387 nba = func->getAttr<NoBuiltinAttr>();
394 if (targetDecl->
hasAttr<ConstAttr>()) {
397 sideEffect = cir::SideEffect::Const;
398 }
else if (targetDecl->
hasAttr<PureAttr>()) {
400 sideEffect = cir::SideEffect::Pure;
403 attrs.set(cir::CIRDialect::getSideEffectAttrName(),
409 if (targetDecl->
hasAttr<ReturnsNonNullAttr>() &&
410 !codeGenOpts.NullPointerIsValid)
411 retAttrs.set(mlir::LLVM::LLVMDialect::getNonNullAttrName(),
413 if (targetDecl->
hasAttr<AnyX86NoCallerSavedRegistersAttr>())
414 addUnitAttr(cir::CIRDialect::getNoCallerSavedRegsAttrName());
417 if (targetDecl->
hasAttr<LeafAttr>())
418 addUnitAttr(cir::CIRDialect::getNoCallbackAttrName());
422 if (
auto *allocSizeAttr = targetDecl->
getAttr<AllocSizeAttr>()) {
423 unsigned size = allocSizeAttr->getElemSizeParam().getLLVMIndex();
425 if (allocSizeAttr->getNumElemsParam().isValid()) {
426 unsigned numElts = allocSizeAttr->getNumElemsParam().getLLVMIndex();
427 attrs.set(cir::CIRDialect::getAllocSizeAttrName(),
428 builder.getDenseI32ArrayAttr(
429 {static_cast<int>(size), static_cast<int>(numElts)}));
431 attrs.set(cir::CIRDialect::getAllocSizeAttrName(),
432 builder.getDenseI32ArrayAttr({static_cast<int>(size)}));
440 if (langOpts.OffloadUniformBlock)
441 addUnitAttr(cir::CIRDialect::getUniformWorkGroupSizeAttrName());
443 if (langOpts.CUDA && !langOpts.CUDAIsDevice &&
444 targetDecl->
hasAttr<CUDAGlobalAttr>()) {
448 auto attr = cir::CUDAKernelNameAttr::get(
451 attrs.set(
attr.getMnemonic(),
attr);
456 if (
auto *modularFormat = targetDecl->
getAttr<ModularFormatAttr>()) {
458 StringRef
type =
format->getType()->getName();
459 std::string formatIdx = std::to_string(
format->getFormatIdx());
460 std::string firstArg = std::to_string(
format->getFirstArg());
462 type, formatIdx, firstArg,
463 modularFormat->getModularImplFn()->getName(),
464 modularFormat->getImplName()};
465 llvm::append_range(args, modularFormat->aspects());
466 attrs.set(cir::CIRDialect::getModularFormatAttrName(),
467 builder.getStringAttr(llvm::join(args,
",")));
473 bool hasOptNoneAttr = targetDecl && targetDecl->
hasAttr<OptimizeNoneAttr>();
485 if (targetDecl->
hasAttr<ZeroCallUsedRegsAttr>()) {
488 targetDecl->
getAttr<ZeroCallUsedRegsAttr>()->getZeroCallUsedRegs();
490 cir::CIRDialect::getZeroCallUsedRegsAttrName(),
491 mlir::StringAttr::get(
493 ZeroCallUsedRegsAttr::ConvertZeroCallUsedRegsKindToStr(
kind)));
496 if (targetDecl->
hasAttr<NoConvergentAttr>())
497 attrs.erase(cir::CIRDialect::getConvergentAttrName());
502 if (!attrOnCallSite) {
506 static const llvm::StringSet<> returnsTwiceFn{
507 "_setjmpex",
"setjmp",
"_setjmp",
"vfork",
508 "sigsetjmp",
"__sigsetjmp",
"savectx",
"getcontext"};
509 if (returnsTwiceFn.contains(name))
510 addUnitAttr(cir::CIRDialect::getReturnsTwiceAttrName());
512 llvm::StringMap<std::string> cpuAndFeatures;
515 for (
const auto &[key, val] : cpuAndFeatures)
516 attrs.set(key, builder.getStringAttr(val));
526 constructFunctionReturnAttributes(info, targetDecl, isThunk, retAttrs);
527 constructFunctionArgumentAttributes(info, targetDecl, isThunk, attrOnCallSite,
531bool CIRGenModule::hasStrictReturn(
QualType retTy,
const Decl *targetDecl) {
537 if (
getLangOpts().Sanitize.has(SanitizerKind::Memory))
544 if (
const FunctionDecl *func = dyn_cast<FunctionDecl>(targetDecl)) {
545 if (func->isExternC())
547 }
else if (
const VarDecl *var = dyn_cast<VarDecl>(targetDecl)) {
549 if (var->isExternC())
562bool CIRGenModule::mayDropFunctionReturn(
const ASTContext &context,
566 if (
const RecordType *recTy =
568 if (
const auto *record = dyn_cast<CXXRecordDecl>(recTy->getDecl()))
569 return record->hasTrivialDestructor();
612 if (
const MatrixType *Matrix = dyn_cast<MatrixType>(clangTy))
624 if (langOpts.NoHonorInfs)
626 if (langOpts.NoHonorNaNs)
631void CIRGenModule::constructFunctionReturnAttributes(
633 mlir::NamedAttrList &retAttrs) {
635 QualType retTy =
info.getReturnType();
636 const cir::ABIArgInfo retInfo =
info.getReturnInfo();
639 if (codeGenOpts.EnableNoundefAttrs && hasStrictReturn(retTy, targetDecl) &&
642 retAttrs.set(mlir::LLVM::LLVMDialect::getNoUndefAttrName(),
647 retAttrs.set(mlir::LLVM::LLVMDialect::getNoFPClassAttrName(),
648 builder.getI64IntegerAttr(mask));
654 if (
const auto *refTy = retTy->
getAs<ReferenceType>()) {
655 QualType pointeeTy = refTy->getPointeeType();
657 retAttrs.set(mlir::LLVM::LLVMDialect::getDereferenceableAttrName(),
658 builder.getI64IntegerAttr(
661 if (
getTypes().getTargetAddressSpace(pointeeTy) == 0 &&
662 !codeGenOpts.NullPointerIsValid)
663 retAttrs.set(mlir::LLVM::LLVMDialect::getNonNullAttrName(),
667 retAttrs.set(mlir::LLVM::LLVMDialect::getAlignAttrName(),
668 builder.getI64IntegerAttr(
674void CIRGenModule::constructFunctionArgumentAttributes(
676 bool attrOnCallSite, llvm::MutableArrayRef<mlir::NamedAttrList> argAttrs) {
681 if (
info.isInstanceMethod() && !isThunk) {
682 QualType thisPtrTy =
info.arguments()[0];
688 if (!codeGenOpts.NullPointerIsValid &&
689 getTypes().getTargetAddressSpace(thisPtrTy) == 0) {
690 argAttrs[0].set(mlir::LLVM::LLVMDialect::getDereferenceableAttrName(),
691 builder.getI64IntegerAttr(
693 argAttrs[0].set(mlir::LLVM::LLVMDialect::getNonNullAttrName(),
700 mlir::LLVM::LLVMDialect::getDereferenceableOrNullAttrName(),
701 builder.getI64IntegerAttr(
bytes));
705 mlir::LLVM::LLVMDialect::getAlignAttrName(),
706 builder.getI64IntegerAttr(
723 const auto *fd = dyn_cast_or_null<FunctionDecl>(targetDecl);
728 SmallVector<const ParmVarDecl *> parmDecls;
729 parmDecls.reserve(argAttrs.size());
731 if (
info.isInstanceMethod())
732 parmDecls.push_back(
nullptr);
733 parmDecls.insert(parmDecls.end(), fd->param_begin(), fd->param_end());
735 parmDecls.resize(argAttrs.size(),
nullptr);
737 for (
const auto &[argAttrList, argCanType, pvd] :
738 llvm::zip_equal(argAttrs,
info.arguments(), parmDecls)) {
740 QualType argType = argCanType;
743 if (codeGenOpts.EnableNoundefAttrs &&
745 argAttrList.set(mlir::LLVM::LLVMDialect::getNoUndefAttrName(),
753 if (
const auto *refTy = argType->
getAs<ReferenceType>()) {
756 argAttrList.set(mlir::LLVM::LLVMDialect::getDereferenceableAttrName(),
757 builder.getI64IntegerAttr(
759 if (
getTypes().getTargetAddressSpace(pointeeTy) == 0 &&
760 !codeGenOpts.NullPointerIsValid)
761 argAttrList.set(mlir::LLVM::LLVMDialect::getNonNullAttrName(),
765 mlir::LLVM::LLVMDialect::getAlignAttrName(),
766 builder.getI64IntegerAttr(
772 argAttrList.set(mlir::LLVM::LLVMDialect::getNoFPClassAttrName(),
773 builder.getI64IntegerAttr(mask));
777 if (!attrOnCallSite && pvd && pvd->getType()->isPointerType() &&
778 pvd->getType().isRestrictQualified() && !fd->getBuiltinID())
779 argAttrList.set(mlir::LLVM::LLVMDialect::getNoAliasAttrName(),
784 if (pvd && argType->
isAnyPointerType() && !codeGenOpts.NullPointerIsValid) {
785 unsigned srcIdx = pvd->getFunctionScopeIndex();
786 if (pvd->hasAttr<NonNullAttr>() ||
787 (fd->getAttr<NonNullAttr>() &&
788 fd->getAttr<NonNullAttr>()->isNonNull(srcIdx)))
789 argAttrList.set(mlir::LLVM::LLVMDialect::getNonNullAttrName(),
809 if (!fpt->hasExtParameterInfos()) {
810 prefix.append(fpt->param_type_begin(), fpt->param_type_end());
817 prefix.reserve(prefix.size() + fpt->getNumParams());
819 fpt->getExtParameterInfos();
820 assert(extInfos.size() == fpt->getNumParams());
821 for (
auto [paramType, extInfo] : llvm::zip_equal(
822 llvm::make_range(fpt->param_type_begin(), fpt->param_type_end()),
824 prefix.push_back(paramType);
825 if (extInfo.hasPassObjectSize())
837 bool passParams =
true;
839 if (
auto *cd = dyn_cast<CXXConstructorDecl>(md)) {
842 if (
auto inherited = cd->getInheritedConstructor())
853 theCXXABI.buildStructorSignature(gd, argTypes);
857 (passParams && md->isVariadic() ?
RequiredArgs(argTypes.size())
860 CanQualType resultType = theCXXABI.hasThisReturn(gd) ? argTypes.front()
861 : theCXXABI.hasMostDerivedReturn(gd)
862 ? astContext.VoidPtrTy
865 assert(!theCXXABI.hasThisReturn(gd) &&
866 "Please send PR with a test and remove this");
872 fpt->getExtInfo(), required);
888 cgm.errorNYI(
"deriveThisType: no record decl");
911 fpt->getExtInfo(), required);
925 if (
type->isReferenceType()) {
931 "emitDelegateCallArg: ObjCAutoRefCount");
940 if (
type->isRecordType() &&
941 type->castAsRecordDecl()->isParamDestroyedInCallee() &&
944 "emitDelegateCallArg: callee-destructed param");
955 if (
const auto *proto = dyn_cast<FunctionProtoType>(fnType)) {
961 if (proto->isVariadic())
965 cgm.
errorNYI(
"call to function without a prototype");
968 for (
const CallArg &arg : args)
986 unsigned extraPrefixArgs,
unsigned extraSuffixArgs,
bool passProtoArgs) {
990 for (
const auto &arg : args)
991 argTypes.push_back(astContext.getCanonicalParamType(arg.ty));
994 unsigned totalPrefixArgs = 1 + extraPrefixArgs;
999 fpt, totalPrefixArgs + extraSuffixArgs)
1003 if (theCXXABI.hasThisReturn(gd))
1005 "arrangeCXXConstructorCall: hasThisReturn");
1006 if (theCXXABI.hasMostDerivedReturn(gd))
1008 "arrangeCXXConstructorCall: hasMostDerivedReturn");
1015 fpt->getExtInfo(), required);
1026 assert(numPrefixArgs + 1 <= args.size() &&
1027 "Emitting a call with less args than the required prefix?");
1031 for (
const CallArg &arg : args)
1032 argTypes.push_back(astContext.getCanonicalParamType(arg.ty));
1037 true, argTypes, proto->
getExtInfo(), required);
1050 for (
const CallArg &arg : args)
1051 argTypes.push_back(astContext.getCanonicalParamType(arg.ty));
1062 if (fd->
hasAttr<CUDAGlobalAttr>()) {
1091 auto *thisType = theCXXABI.getThisArgumentTypeForMethod(md);
1113 return ::arrangeCIRFunctionInfo(
1114 *
this,
true, argTypes,
1122 if (
const auto *md = dyn_cast<CXXMethodDecl>(fd))
1123 if (md->isInstance())
1158 if (!ac.
getDecl() || !(
sanOpts.has(SanitizerKind::NonnullAttribute) ||
1159 sanOpts.has(SanitizerKind::NullabilityArg)))
1161 cgm.errorNYI(
"non-null arg check is NYI");
1164static cir::CIRCallOpInterface
1166 cir::FuncType indirectFuncTy, mlir::Value indirectFuncVal,
1167 cir::FuncOp directFuncOp,
1169 const mlir::NamedAttrList &attrs,
1171 const mlir::NamedAttrList &retAttrs) {
1176 assert(builder.getInsertionBlock() &&
"expected valid basic block");
1179 if (indirectFuncTy) {
1183 cirCallArgs, attrs, argAttrs, retAttrs);
1185 op = builder.
createCallOp(callLoc, directFuncOp, cirCallArgs, attrs,
1186 argAttrs, retAttrs);
1196 return ::arrangeCIRFunctionInfo(*
this,
false, argTypes,
1212 cir::CIRCallOpInterface *callOp,
1213 bool isMustTail, mlir::Location loc) {
1221 const FunctionDecl *calleeDecl = dyn_cast_or_null<FunctionDecl>(targetDecl);
1226 for (
auto [argNo, arg, canQualArgType] :
1227 llvm::enumerate(args, funcInfo.
argTypes())) {
1233 if (!mlir::isa<cir::RecordType>(argType) &&
1234 !mlir::isa<cir::ComplexType>(argType)) {
1236 if (arg.isAggregate())
1237 cgm.errorNYI(loc,
"emitCall: aggregate call argument");
1238 v = arg.getKnownRValue().getValue();
1241 if (argType != v.getType() && mlir::isa<cir::IntType>(v.getType()))
1242 cgm.errorNYI(loc,
"emitCall: widening integer call argument");
1246 if (argType != v.getType()) {
1247 auto argPtrTy = mlir::dyn_cast<cir::PointerType>(argType);
1248 auto vPtrTy = mlir::dyn_cast<cir::PointerType>(v.getType());
1249 if (argPtrTy && vPtrTy &&
1250 argPtrTy.getPointee() == vPtrTy.getPointee() &&
1251 argPtrTy.getAddrSpace() != vPtrTy.getAddrSpace()) {
1261 cirCallArgs[argNo] = v;
1264 if (!arg.isAggregate()) {
1266 arg.copyInto(*
this, src, loc);
1268 src = arg.hasLValue() ? arg.getKnownLValue().getAddress()
1269 : arg.getKnownRValue().getAggregateAddress();
1276 mlir::Location argLoc = loc;
1289 if (srcTy != argType) {
1290 cgm.errorNYI(loc,
"emitCall: source type does not match argument type");
1306 cirCallArgs[argNo] = builder.createLoad(argLoc, src);
1315 mlir::NamedAttrList attrs;
1316 std::vector<mlir::NamedAttrList> argAttrs(funcInfo.
arguments().size());
1317 mlir::NamedAttrList retAttrs;
1319 if (
auto calleeFuncOp = dyn_cast<cir::FuncOp>(calleePtr))
1320 funcName = calleeFuncOp.getName();
1324 cir::CallingConv callingConv;
1325 cir::SideEffect sideEffect;
1327 attrs, argAttrs, retAttrs, callingConv, sideEffect,
1330 auto resolvedFuncOpFromGlobal = [&](mlir::Operation *op) -> cir::FuncOp {
1331 if (
auto fnOp = dyn_cast<cir::FuncOp>(op))
1333 if (
auto getGlobalOp = dyn_cast<cir::GetGlobalOp>(op)) {
1338 mlir::Operation *globalOp =
cgm.getGlobalValue(getGlobalOp.getName());
1339 assert(globalOp &&
"undefined global function");
1345 cir::FuncType indirectFuncTy;
1346 mlir::Value indirectFuncVal;
1347 cir::FuncOp directFuncOp;
1356 if (cir::FuncOp candidate = resolvedFuncOpFromGlobal(calleePtr)) {
1357 if (candidate.getFunctionType() == cirFuncTy) {
1358 directFuncOp = candidate;
1360 mlir::Value addr = cir::GetGlobalOp::create(
1361 builder, loc, cir::PointerType::get(candidate.getFunctionType()),
1362 candidate.getSymName());
1363 indirectFuncTy = cirFuncTy;
1365 builder.createBitcast(addr, cir::PointerType::get(cirFuncTy));
1368 [[maybe_unused]] mlir::ValueTypeRange<mlir::ResultRange> resultTypes =
1369 calleePtr->getResultTypes();
1370 [[maybe_unused]]
auto funcPtrTy =
1371 mlir::dyn_cast<cir::PointerType>(resultTypes.front());
1372 assert(funcPtrTy && mlir::isa<cir::FuncType>(funcPtrTy.getPointee()) &&
1373 "expected pointer to function");
1375 indirectFuncTy = cirFuncTy;
1376 indirectFuncVal = calleePtr->getResult(0);
1383 bool cannotThrow = attrs.getNamed(
"nothrow").has_value();
1386 mlir::Location callLoc = loc;
1387 cir::CIRCallOpInterface theCall =
1388 emitCallLikeOp(*
this, loc, indirectFuncTy, indirectFuncVal, directFuncOp,
1389 cirCallArgs, isInvoke, attrs, argAttrs, retAttrs);
1399 theCall.setInlineKind(cir::InlineKind::NoInline);
1401 !
cgm.getTargetCIRGenInfo().wouldInliningViolateFunctionCallABI(
1402 callerDecl, calleeDecl))
1403 theCall.setInlineKind(cir::InlineKind::AlwaysInline);
1409 if (triple.isPPC() || triple.isMIPS()) {
1411 "musttail call target legality checks");
1421 "musttail call that skips cleanups");
1425 theCall->setAttr(cir::CIRDialect::getMustTailAttrName(),
1426 builder.getUnitAttr());
1429 cir::ReturnOp::create(builder, loc);
1431 cir::ReturnOp::create(builder, loc, theCall->getResult(0));
1436 builder.createBlock(builder.getBlock()->getParent());
1452 mlir::ResultRange results = theCall->getOpResults();
1453 assert(results.size() <= 1 &&
"multiple returns from a call");
1460 mlir::ResultRange results = theCall->getOpResults();
1461 assert(results.size() == 1 &&
"unexpected number of returns");
1465 if (results[0].
getType() != retCIRTy)
1466 cgm.errorNYI(loc,
"bitcast on function return value");
1468 mlir::Region *region = builder.getBlock()->getParent();
1469 if (region != theCall->getParentRegion())
1470 cgm.errorNYI(loc,
"function calls with cleanup");
1475 mlir::ResultRange results = theCall->getOpResults();
1476 assert(!results.empty() &&
1477 "Expected at least one result for complex rvalue");
1481 llvm_unreachable(
"Invalid evaluation kind");
1485 mlir::Location loc)
const {
1487 if (!hasLV &&
rv.isScalar())
1489 else if (!hasLV &&
rv.isComplex())
1499 mlir::NamedAttrList attrs) {
1504 cir::CallOp call = builder.createCallOp(loc, callee, args);
1505 assert(call->getNumResults() <= 1 &&
1506 "runtime functions have at most 1 result");
1509 call->setAttrs(attrs);
1511 if (call->getNumResults() == 0)
1514 return call->getResult(0);
1520 "reference binding to unmaterialized r-value!");
1536 bool destroyedInCallee =
true;
1538 destroyedInCallee = rd->hasNonTrivialDestructor();
1540 if (destroyedInCallee)
1545 args.
add(rv, argType);
1547 if (destroyedInCallee &&
getLangOpts().Exceptions)
1549 "callee-destructed param with exceptions");
1564QualType CIRGenFunction::getVarArgType(
const Expr *arg) {
1569 return arg->getType();
1572 cgm.
errorNYI(arg->getSourceRange(),
"getVarArgType: NYI for Windows target");
1573 return arg->getType();
1590 llvm::iterator_range<clang::CallExpr::const_arg_iterator> argRange,
1597 bool isVariadic =
false;
1602 isVariadic = fpt->isVariadic();
1604 argTypes.assign(fpt->param_type_begin() + paramsToSkip,
1605 fpt->param_type_end());
1609 for (
const clang::Expr *a : llvm::drop_begin(argRange, argTypes.size()))
1610 argTypes.push_back(isVariadic ? getVarArgType(a) : a->getType());
1611 assert(argTypes.size() == (
size_t)(argRange.end() - argRange.begin()));
1618 auto leftToRight =
true;
1621 auto maybeEmitImplicitObjectSize = [&](
size_t i,
const Expr *arg,
1630 assert(emittedArg.getValue() &&
"We emitted nothing for the arg?");
1633 emittedArg.getValue(), ps->isDynamic());
1639 std::iter_swap(args.rbegin(), std::next(args.rbegin()));
1643 size_t callArgsStart = args.size();
1644 for (
size_t i = 0; i != argTypes.size(); ++i) {
1645 size_t idx = leftToRight ? i : argTypes.size() - i - 1;
1647 size_t initialArgSize = args.size();
1653 assert(initialArgSize + 1 == args.size() &&
1654 "The code below depends on only adding one arg per emitCallArg");
1655 (void)initialArgSize;
1659 if (!args.back().hasLValue()) {
1660 RValue rvArg = args.back().getKnownRValue();
1662 maybeEmitImplicitObjectSize(idx, *currentArg, rvArg);
1666 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 unsigned getNoFPClassTestMask(const LangOptions &langOpts)
Compute the nofpclass mask for FP types based on language options.
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 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)
static void addAttributesFromFunctionProtoType(CIRGenBuilderTy &builder, mlir::NamedAttrList &attrs, const FunctionProtoType *fpt)
static llvm::StringLiteral getZeroCallUsedRegsKindStr(llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind k)
static CanQual< FunctionProtoType > getFormalType(const CXXMethodDecl *md)
Returns the canonical formal type of the given C++ method.
static const CIRGenFunctionInfo & arrangeFreeFunctionLikeCall(CIRGenTypes &cgt, CIRGenModule &cgm, const CallArgList &args, const FunctionType *fnType)
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 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::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={})
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
void emitCallArgs(CallArgList &args, PrototypeWrapper prototype, llvm::iterator_range< clang::CallExpr::const_arg_iterator > argRange, AbstractCallee callee=AbstractCallee(), unsigned paramsToSkip=0)
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.
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.
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
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)
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={})
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.
std::optional< mlir::Location > currSrcLoc
Use to track source locations across nested visitor traversals.
clang::ASTContext & getContext() const
RValue emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, const CallArgList &args, cir::CIRCallOpInterface *callOp, bool isMustTail, mlir::Location loc)
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.
llvm::StringRef getMangledName(clang::GlobalDecl gd)
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()
CharUnits getMinimumObjectSize(QualType ty)
Returns the minimum object size for an object of the given type.
const cir::CIRDataLayout getDataLayout() const
const clang::CodeGenOptions & getCodeGenOpts() const
const clang::LangOptions & getLangOpts() const
void constructAttributeList(llvm::StringRef name, const CIRGenFunctionInfo &info, CIRGenCalleeInfo calleeInfo, mlir::NamedAttrList &attrs, llvm::MutableArrayRef< mlir::NamedAttrList > argAttrs, mlir::NamedAttrList &retAttrs, cir::CallingConv &callingConv, cir::SideEffect &sideEffect, bool attrOnCallSite, bool isThunk)
Get the CIR attributes and calling convention to use for a particular function type.
const TargetCIRGenInfo & getTargetCIRGenInfo()
mlir::MLIRContext & getMLIRContext()
CIRGenCXXABI & getCXXABI() const
clang::CharUnits getNaturalPointeeTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo=nullptr)
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)
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.
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
getQuantity - 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...
This represents one expression.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
Represents a function declaration or definition.
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
GlobalDecl getWithKernelReferenceKind(KernelReferenceKind Kind)
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.
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.
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 ...
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.
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 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.