23#include "llvm/Support/TrailingObjects.h"
29struct MemberCallInfo {
43 "Trying to emit a member or operator call expr on a static method!");
58 unsigned prefixSize = args.size() - 1;
73 fpt->getNumParams() == 0 &&
74 "No CallExpr specified for function with non-zero number of arguments");
78 return {required, prefixSize};
107 auto [ calleePtr, adjustedThis] =
108 builder.createGetMethod(loc, memFnPtr, thisAddr.getPointer());
120 return emitCall(
cgm.getTypes().arrangeCXXMethodCall(argsList, fpt, required,
132 bool canUseVirtualCall = md->
isVirtual() && !hasQualifier;
148 if (
auto *oce = dyn_cast<CXXOperatorCallExpr>(ce)) {
149 if (oce->isAssignmentOp()) {
150 rtlArgs = &rtlArgStorage;
169 "emitCXXMemberOrOperatorMemberCallExpr: constructor call");
179 devirtualizedMethod ? devirtualizedMethod : md;
181 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(calleeDecl))
182 fInfo = &
cgm.getTypes().arrangeCXXStructorDeclaration(
185 fInfo = &
cgm.getTypes().arrangeCXXMethodDeclaration(calleeDecl);
187 cir::FuncType ty =
cgm.getTypes().getFunctionType(*fInfo);
198 bool useVirtualCall = canUseVirtualCall && !devirtualizedMethod;
200 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(calleeDecl)) {
202 "Destructor shouldn't have explicit parameters");
203 assert(
returnValue.isNull() &&
"Destructor shouldn't have return value");
204 if (useVirtualCall) {
212 if (!devirtualizedMethod) {
214 cgm.getAddrOfCXXStructor(globalDecl, fInfo, ty), globalDecl);
232 if (useVirtualCall) {
238 "emitCXXMemberOrOperatorMemberCallExpr: AppleKext");
248 cgm.getCXXABI().adjustThisArgumentForVirtualFunctionCall(
249 *
this, calleeDecl, thisPtr.
getAddress(), useVirtualCall);
263 "Trying to emit a member call expr on a static method!");
273 cgm.errorNYI(
"CUDA Device side kernel call");
284 *
this, md, thisPtr, implicitParam, implicitParamTy, ce, args, rtlArgs);
285 auto &fnInfo =
cgm.getTypes().arrangeCXXMethodCall(
286 args, fpt, callInfo.reqArgs, callInfo.prefixSize);
287 assert((ce ||
currSrcLoc) &&
"expected source location");
322 "emitNullBaseClassInitialization: base constant is not null");
331 assert(stores.size() == 1 &&
"Expected only one store");
333 "Expected store to begin at offset zero");
343 assert(!dest.
isIgnored() &&
"Must have a destination!");
390 bool forVirtualBase =
false;
391 bool delegating =
false;
403 forVirtualBase =
true;
428 unsigned minElements,
429 mlir::Value &numElements,
430 mlir::Value &sizeWithoutCookie) {
438 return sizeWithoutCookie;
455 llvm::APInt arraySizeMultiplier(sizeWidth, 1);
458 type = cat->getElementType();
459 arraySizeMultiplier *= cat->getSize();
463 llvm::APInt typeSizeMultiplier(sizeWidth, typeSize.
getQuantity());
464 typeSizeMultiplier *= arraySizeMultiplier;
467 llvm::APInt cookieSize(sizeWidth,
477 mlir::Attribute constNumElements =
480 if (constNumElements) {
482 const llvm::APInt &count =
483 mlir::cast<cir::IntAttr>(constNumElements).getValue();
485 [[maybe_unused]]
unsigned numElementsWidth = count.getBitWidth();
486 bool hasAnyOverflow =
false;
492 assert(!count.isNegative() &&
"Expected non-negative array size");
493 assert(numElementsWidth == sizeWidth &&
494 "Expected a size_t array size constant");
497 llvm::APInt adjustedCount = count.zextOrTrunc(sizeWidth);
509 llvm::APInt allocationSize =
510 adjustedCount.umul_ov(typeSizeMultiplier, overflow);
513 assert(!overflow &&
"Overflow in array allocation size");
516 if (cookieSize != 0) {
520 loc, allocationSize.zextOrTrunc(sizeWidth));
522 allocationSize = allocationSize.uadd_ov(cookieSize, overflow);
523 hasAnyOverflow |= overflow;
527 if (hasAnyOverflow) {
536 auto numElementsType = mlir::cast<cir::IntType>(numElements.getType());
537 unsigned numElementsWidth = numElementsType.getWidth();
546 (*e->
getArraySize())->getType()->isSignedIntegerOrEnumerationType();
561 mlir::Value hasOverflow;
566 if (numElementsWidth > sizeWidth) {
567 llvm::APInt threshold =
568 llvm::APInt::getOneBitSet(numElementsWidth, sizeWidth);
571 mlir::Value unsignedNumElements = numElements;
576 mlir::Value thresholdV =
579 loc, cir::CmpOpKind::ge, unsignedNumElements, thresholdV);
581 unsignedNumElements, mlir::cast<cir::IntType>(cgf.
sizeTy));
584 }
else if (isSigned) {
585 if (numElementsWidth < sizeWidth)
594 if (typeSizeMultiplier == 1)
596 loc, cir::CmpOpKind::lt, numElements,
601 numElements, mlir::cast<cir::IntType>(cgf.
sizeTy));
604 }
else if (numElementsWidth < sizeWidth) {
606 numElements, mlir::cast<cir::IntType>(cgf.
sizeTy));
609 assert(numElements.getType() == cgf.
sizeTy);
615 loc, llvm::APInt(sizeWidth, minElements));
617 numElements, minElementsV);
618 }
else if (numElementsWidth > sizeWidth) {
623 loc, llvm::APInt(sizeWidth, minElements));
640 if (typeSizeMultiplier != 1) {
642 auto mulOp = cir::MulOverflowOp::create(
650 hasOverflow = mulOp.getOverflow();
652 size = mulOp.getResult();
655 if (arraySizeMultiplier != 1) {
658 if (typeSize.
isOne()) {
659 assert(arraySizeMultiplier == typeSizeMultiplier);
671 assert(arraySizeMultiplier == 1);
675 if (cookieSize != 0) {
676 sizeWithoutCookie = size;
678 auto addOp = cir::AddOverflowOp::create(
686 hasOverflow = addOp.getOverflow();
688 size = addOp.getResult();
695 mlir::Value allOnes =
702 sizeWithoutCookie = size;
704 assert(sizeWithoutCookie &&
"didn't set sizeWithoutCookie?");
715 cir::CIRCallOpInterface callOrTryCall;
729 calleePtr->hasAttr(cir::CIRDialect::getNoBuiltinAttrName())) {
730 callOrTryCall->setAttr(cir::CIRDialect::getBuiltinAttrName(),
731 mlir::UnitAttr::get(callOrTryCall->getContext()));
744 assert(op == OO_New || op == OO_Delete);
750 if (
const auto *funcDecl = dyn_cast<FunctionDecl>(
decl)) {
752 if (
sanOpts.has(SanitizerKind::AllocToken)) {
755 cgm.errorNYI(
"Alloc token sanitizer not yet supported!");
764 llvm_unreachable(
"predeclared global operator new/delete is missing");
768template <
typename Traits>
struct PlacementArg {
769 typename Traits::RValueTy argValue;
776template <
typename Traits>
777class CallDeleteDuringNew final
778 :
public EHScopeStack::Cleanup,
779 private llvm::TrailingObjects<CallDeleteDuringNew<Traits>,
780 PlacementArg<Traits>> {
782 llvm::TrailingObjects<CallDeleteDuringNew<Traits>, PlacementArg<Traits>>;
784 using TrailingObj::getTrailingObjects;
787 typedef typename Traits::ValueTy ValueTy;
789 typedef typename Traits::RValueTy RValueTy;
791 unsigned numPlacementArgs : 30;
793 unsigned passAlignmentToPlacementDelete : 1;
799 PlacementArg<Traits> *getPlacementArgs() {
return getTrailingObjects(); }
801 void setPlacementArg(
unsigned i, RValueTy argValue,
QualType argType) {
802 assert(i < numPlacementArgs &&
"index out of range");
803 getPlacementArgs()[i] = {argValue, argType};
807 static size_t getExtraSize(
size_t numPlacementArgs) {
808 return TrailingObj::template additionalSizeToAlloc<PlacementArg<Traits>>(
812 CallDeleteDuringNew(
size_t numPlacementArgs,
813 const FunctionDecl *operatorDelete, ValueTy ptr,
815 const ImplicitAllocationParameters &iap,
816 CharUnits allocAlign,
const CallArgList *newArgs,
817 unsigned numNonPlacementArgs, CIRGenFunction *cgf,
819 : numPlacementArgs(numPlacementArgs),
821 operatorDelete(operatorDelete), ptr(ptr), allocSize(allocSize),
822 allocAlign(allocAlign) {
823 for (
unsigned i = 0, n = numPlacementArgs; i != n; ++i) {
824 const CallArg &
arg = (*newArgs)[i + numNonPlacementArgs];
825 setPlacementArg(i,
arg.getRValue(*cgf, loc),
arg.ty);
829 void emit(CIRGenFunction &cgf, Flags flags)
override {
830 const auto *fpt = operatorDelete->
getType()->
castAs<FunctionProtoType>();
831 CallArgList deleteArgs;
833 unsigned firstNonTypeArg = 0;
839 deleteArgs.add(Traits::get(cgf, ptr), fpt->getParamType(firstNonTypeArg));
842 UsualDeleteParams params;
843 if (numPlacementArgs) {
857 "should not call destroying delete in a new-expression");
861 deleteArgs.add(Traits::get(cgf, allocSize),
869 cgf.
cgm.
errorNYI(
"CallDeleteDuringNew: aligned allocation");
872 for (
unsigned i = 0; i != numPlacementArgs; ++i) {
873 auto arg = getPlacementArgs()[i];
874 deleteArgs.add(Traits::get(cgf,
arg.argValue),
arg.argType);
886 Address newPtr, mlir::Value allocSize,
894 struct DirectCleanupTraits {
895 typedef mlir::Value ValueTy;
901 typedef CallDeleteDuringNew<DirectCleanupTraits> DirectCleanup;
907 allocAlign, &newArgs, numNonPlacementArgs, &cgf,
914 "enterNewDeleteCleanup: conditional branch");
940 llvm_unreachable(
"bad evaluation kind");
945 Address beginPtr, mlir::Value numElements,
946 mlir::Value allocSizeWithoutCookie) {
954 unsigned initListElements = 0;
962 auto tryMemsetInitialization = [&]() ->
bool {
963 mlir::Location loc = numElements.getLoc();
967 if (!
cgm.getTypes().isZeroInitializable(elementType))
974 auto remainingSize = allocSizeWithoutCookie;
975 if (initListElements) {
977 unsigned initializedSize =
980 cir::ConstantOp initSizeOp =
981 builder.getConstInt(loc, remainingSize.getType(), initializedSize);
982 remainingSize = builder.createSub(loc, remainingSize, initSizeOp);
988 builder.createMemSet(loc, castOp, builder.getConstInt(loc,
cgm.uInt8Ty, 0),
997 const Expr *ignoreParen =
nullptr;
1000 cplie = dyn_cast<CXXParenListInitExpr>(ignoreParen);
1001 sl = dyn_cast<StringLiteral>(ignoreParen);
1002 ocee = dyn_cast<ObjCEncodeExpr>(ignoreParen);
1005 if (ile || cplie || sl || ocee) {
1010 "emitNewArrayInitializer: string literal init");
1016 initListElements = initExprs.size();
1025 "emitNewArrayInitializer: constant array init");
1032 "emitNewArrayInitializer: init requires dtor");
1039 for (
const Expr *ie : initExprs) {
1044 cgm.errorNYI(ie->getSourceRange(),
1045 "emitNewArrayInitializer: update dtor cleanup ptr");
1053 mlir::Location loc =
getLoc(ie->getExprLoc());
1054 mlir::Value castOp = builder.createPtrBitcast(
1056 mlir::Value offsetOp = builder.getSignedInt(loc, 1, 32);
1057 mlir::Value dataPtr = builder.createPtrStride(loc, castOp, offsetOp);
1069 auto *subIle = dyn_cast<InitListExpr>(init);
1072 assert(subIle->getNumInits() == 0 &&
"explicit inits in array filler?");
1073 init = subIle->getArrayFiller();
1082 auto constOp = mlir::dyn_cast<cir::ConstantOp>(numElements.getDefiningOp());
1084 auto constIntAttr = mlir::dyn_cast<cir::IntAttr>(constOp.getValue());
1086 if (constIntAttr && constIntAttr.getUInt() <= initListElements)
1090 assert(init &&
"have trailing elements to initialize but no initializer");
1099 if (!cce->requiresZeroInitialization())
1102 cgm.errorNYI(cce->getSourceRange(),
1103 "emitNewArrayInitializer: trivial ctor zero-init");
1115 mlir::Type initType =
convertType(cce->getType());
1117 if (initListElements) {
1122 auto constIntAttr = mlir::cast<cir::IntAttr>(constOp.getValue());
1123 uint64_t numRemainingElements =
1124 constIntAttr.getUInt() - initListElements;
1127 numElements.getType(), numRemainingElements);
1134 if (!mlir::isa<cir::ArrayType>(initType))
1135 initType = cir::ArrayType::get(initType, numRemainingElements);
1138 "emitNewArrayInitializer: numRemainingElements with "
1139 "non-constant count");
1147 cce->requiresZeroInitialization());
1148 if (
getContext().getTargetInfo().emitVectorDeletingDtors(
1151 "emitNewArrayInitializer: emitVectorDeletingDtors");
1158 if (tryMemsetInitialization())
1161 "emitNewArrayInitializer: implicit value init");
1166 "emitNewArrayInitializer: unsupported initializer");
1171 QualType elementType, mlir::Type elementTy,
1172 Address newPtr, mlir::Value numElements,
1173 mlir::Value allocSizeWithoutCookie) {
1177 allocSizeWithoutCookie);
1190 assert(!thisTy.
isNull());
1192 "Pointer/Object mixup");
1198 implicitParamTy, ce, args,
nullptr);
1199 assert((ce || dtor.
getDecl()) &&
"expected source location provider");
1201 return emitCall(
cgm.getTypes().arrangeCXXStructorDeclaration(dtor), callee,
1212 cgm.errorNYI(
expr->getExprLoc(),
1213 "emitCXXPseudoDestructorExpr: Objective-C lifetime is NYI");
1233 CallObjectDelete(mlir::Value ptr,
const FunctionDecl *operatorDelete,
1235 : ptr(ptr), operatorDelete(operatorDelete), elementType(elementType) {}
1260 if (rd->hasDefinition() && !rd->hasTrivialDestructor()) {
1261 dtor = rd->getDestructor();
1275 cgf.
ehStack.pushCleanup<CallObjectDelete>(
1281 false, ptr, elementType);
1302 cir::YieldOp thenYield;
1303 mlir::Value notNull = builder.createPtrIsNotNull(ptr.
getPointer());
1307 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1308 thenYield = builder.createYield(loc);
1313 mlir::OpBuilder::InsertionGuard guard(builder);
1314 builder.setInsertionPoint(thenYield);
1322 "emitCXXDeleteExpr: destroying operator delete");
1331 cgm.getASTContext().getTargetInfo().emitVectorDeletingDtors(
1332 cgm.getASTContext().getLangOpts())) {
1334 "emitCXXDeleteExpr: emitVectorDeletingDtors");
1339 cir::FuncOp operatorDeleteFn =
cgm.getAddrOfFunction(operatorDelete);
1341 mlir::FlatSymbolRefAttr::get(operatorDeleteFn.getSymNameAttr());
1343 auto deleteParams = cir::UsualDeleteParamsAttr::get(
1347 mlir::FlatSymbolRefAttr elementDtor;
1349 if (rd->hasDefinition() && !rd->hasTrivialDestructor()) {
1353 "emitCXXDeleteExpr: throwing destructor");
1354 cir::FuncOp dtorFn =
1356 elementDtor = mlir::FlatSymbolRefAttr::get(builder.getContext(),
1357 dtorFn.getSymNameAttr());
1361 cir::DeleteArrayOp::create(builder, ptr.
getPointer().getLoc(),
1377 unsigned minElements = 0;
1389 mlir::Value numElements =
nullptr;
1390 mlir::Value allocSizeWithoutCookie =
nullptr;
1392 *
this, e, minElements, numElements, allocSizeWithoutCookie);
1398 if (allocator->isReservedGlobalPlacementOperator()) {
1418 "emitCXXNewExpr: reserved placement new with delete");
1423 unsigned paramsToSkip = 0;
1430 if (allocSize != allocSizeWithoutCookie) {
1432 allocAlign = std::max(allocAlign, cookieAlign);
1455 allocator->isReplaceableGlobalAllocationFunction()) {
1456 const TargetInfo &target =
cgm.getASTContext().getTargetInfo();
1457 unsigned allocatorAlign = llvm::bit_floor(std::min<uint64_t>(
1459 allocationAlign = std::max(
1460 allocationAlign,
getContext().toCharUnitsFromBits(allocatorAlign));
1463 mlir::Value allocPtr = rv.
getValue();
1465 allocPtr, mlir::cast<cir::PointerType>(allocPtr.getType()).getPointee(),
1484 bool useNewDeleteCleanup =
1488 mlir::Operation *cleanupDominator =
nullptr;
1489 if (useNewDeleteCleanup) {
1493 operatorDeleteCleanup =
ehStack.stable_begin();
1499 if (allocSize != allocSizeWithoutCookie) {
1501 allocation =
cgm.getCXXABI().initializeArrayCookie(
1502 *
this, allocation, numElements, e, allocType);
1505 mlir::Type elementTy;
1514 allocation, elementTy);
1518 if (useNewDeleteCleanup) {
1530 if (
cgm.getCodeGenOpts().StrictVTablePointers &&
1531 allocator->isReservedGlobalPlacementOperator())
1537 allocSizeWithoutCookie);
1541 if (useNewDeleteCleanup) {
1542 assert(operatorDeleteCleanup.
isValid());
1545 cleanupDominator->erase();
1546 cir::LoadOp loadResult =
1548 result = result.
withPointer(loadResult.getResult());
1557 mlir::Value ptr,
QualType deleteTy) {
1564 auto paramTypeIt = deleteFTy->param_type_begin();
1569 "emitDeleteCall: type aware delete");
1573 mlir::Value deletePtr =
1574 builder.createBitcast(ptr.getLoc(), ptr,
convertType(argTy));
1580 "emitDeleteCall: destroying delete");
1584 QualType sizeType = *paramTypeIt++;
1586 assert(mlir::isa<cir::IntType>(
convertType(sizeType)) &&
1587 "expected cir::IntType");
1588 cir::ConstantOp size = builder.getConstInt(
1597 "emitDeleteCall: aligned allocation");
1599 assert(paramTypeIt == deleteFTy->param_type_end() &&
1600 "unknown parameter to usual delete function");
1607 mlir::Location loc,
QualType destTy) {
1609 assert(mlir::isa<cir::PointerType>(destCIRTy) &&
1610 "result of dynamic_cast should be a ptr");
1613 mlir::Region *currentRegion = cgf.
getBuilder().getBlock()->getParent();
1620 cgf.
getBuilder().createBlock(currentRegion, currentRegion->end());
1630 cgm.emitExplicitCastExprType(dce,
this);
1642 if (isDynCastToVoid) {
1649 srcRecordTy = srcTy;
1653 assert(srcRecordTy->
isRecordType() &&
"source type must be a record type!");
1659 auto destCirTy = mlir::cast<cir::PointerType>(
convertType(destTy));
1660 return cgm.getCXXABI().emitDynamicCast(*
this, loc, srcRecordTy, destRecordTy,
1661 destCirTy, isRefCast, thisAddr);
1665 mlir::Type typeInfoPtrTy,
1666 bool hasNullCheck) {
1677 mlir::Value isThisNull =
1683 false, [&](mlir::OpBuilder &, mlir::Location loc) {
1684 cgf.cgm.getCXXABI().emitBadTypeidCall(cgf, loc);
1717 auto typeInfoGlobal =
1719 auto getTypeInfo = cir::GetGlobalOp::create(
1720 builder, loc, builder.getPointerTo(typeInfoGlobal.getSymType()),
1721 typeInfoGlobal.getSymName());
1725 return builder.createBitcast(getTypeInfo, resultType);
static void emit(Program &P, llvm::SmallVectorImpl< std::byte > &Code, const T &Val, bool &Success)
Helper to write bytecode and bail out if 32-bit offsets become invalid.
static void emitNewInitializer(CIRGenFunction &cgf, const CXXNewExpr *e, QualType elementType, mlir::Type elementTy, Address newPtr, mlir::Value numElements, mlir::Value allocSizeWithoutCookie)
static mlir::Value emitCXXTypeidFromVTable(CIRGenFunction &cgf, const Expr *e, mlir::Type typeInfoPtrTy, bool hasNullCheck)
static void emitObjectDelete(CIRGenFunction &cgf, const CXXDeleteExpr *de, Address ptr, QualType elementType)
Emit the code for deleting a single object.
static void emitNullBaseClassInitialization(CIRGenFunction &cgf, Address destPtr, const CXXRecordDecl *base)
static void enterNewDeleteCleanup(CIRGenFunction &cgf, const CXXNewExpr *e, Address newPtr, mlir::Value allocSize, CharUnits allocAlign, const CallArgList &newArgs)
Enter a cleanup to call 'operator delete' if the initializer in a new-expression throws.
static mlir::Value emitCXXNewAllocSize(CIRGenFunction &cgf, const CXXNewExpr *e, unsigned minElements, mlir::Value &numElements, mlir::Value &sizeWithoutCookie)
static void storeAnyExprIntoOneUnit(CIRGenFunction &cgf, const Expr *init, QualType allocType, Address newPtr, AggValueSlot::Overlap_t mayOverlap)
static CharUnits calculateCookiePadding(CIRGenFunction &cgf, const CXXNewExpr *e)
static mlir::Value emitDynamicCastToNull(CIRGenFunction &cgf, mlir::Location loc, QualType destTy)
static MemberCallInfo commonBuildCXXMemberOrOperatorCall(CIRGenFunction &cgf, const CXXMethodDecl *md, mlir::Value thisPtr, mlir::Value implicitParam, QualType implicitParamTy, const CallExpr *ce, CallArgList &args, CallArgList *rtlArgs)
static RValue emitNewDeleteCall(CIRGenFunction &cgf, const FunctionDecl *calleeDecl, const FunctionProtoType *calleeType, const CallArgList &args)
Emit a call to an operator new or operator delete function, as implicitly created by new-expressions ...
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines an enumeration for C++ overloaded operators.
static QualType getPointeeType(const MemRegion *R)
cir::ConstantOp getConstant(mlir::Location loc, mlir::TypedAttr attr)
mlir::Value createOr(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createPtrIsNull(mlir::Value ptr)
cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc)
mlir::Value createIntCast(mlir::Value src, mlir::Type newTy)
cir::CmpOp createCompare(mlir::Location loc, cir::CmpOpKind kind, mlir::Value lhs, mlir::Value rhs)
mlir::Value createSelect(mlir::Location loc, mlir::Value condition, mlir::Value trueValue, mlir::Value falseValue)
mlir::Value createMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, OverflowBehavior ob=OverflowBehavior::None)
llvm::TypeSize getTypeSizeInBits(mlir::Type ty) const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
DeclarationNameTable DeclarationNames
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
A builtin binary operation expression such as "x + y" or "x <= y".
Address withPointer(mlir::Value newPtr) const
Return address with different pointer, but same element type and alignment.
mlir::Value getPointer() const
mlir::Type getElementType() const
Address withElementType(CIRGenBuilderTy &builder, mlir::Type ElemTy) const
Return address with different element type, a bitcast pointer, and the same alignment.
clang::CharUnits getAlignment() const
Address withAlignment(clang::CharUnits newAlignment) const
Return address with different alignment, but same pointer and element type.
mlir::Value emitRawPointer() const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
IsZeroed_t isZeroed() const
static AggValueSlot forAddr(Address addr, clang::Qualifiers quals, IsDestructed_t isDestructed, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed)
Address getAddress() const
cir::IntType getSIntNTy(int n)
bool isNullValue(mlir::Attribute attr) const
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, mlir::IntegerAttr align={}, cir::SyncScopeKindAttr scope={}, cir::MemOrderAttr order={})
cir::ConstantOp getConstInt(mlir::Location loc, llvm::APSInt intVal)
cir::IntType getUIntNTy(int n)
virtual void emitVirtualObjectDelete(CIRGenFunction &cgf, const CXXDeleteExpr *de, Address ptr, QualType elementType, const CXXDestructorDecl *dtor)=0
virtual const clang::CXXRecordDecl * getThisArgumentTypeForMethod(const clang::CXXMethodDecl *md)
Get the type of the implicit "this" parameter used by a method.
virtual bool shouldTypeidBeNullChecked(QualType srcTy)=0
virtual mlir::Value emitTypeid(CIRGenFunction &cgf, QualType srcTy, Address thisPtr, mlir::Type typeInfoPtrTy)=0
virtual void emitBadCastCall(CIRGenFunction &cgf, mlir::Location loc)=0
virtual CharUnits getArrayCookieSize(const CXXNewExpr *e)
Returns the extra size required in order to store the array cookie for the given new-expression.
static CIRGenCallee forDirect(mlir::Operation *funcPtr, const CIRGenCalleeInfo &abstractInfo=CIRGenCalleeInfo())
static CIRGenCallee forVirtual(const clang::CallExpr *ce, clang::GlobalDecl md, Address addr, cir::FuncType fTy)
An abstract representation of regular/ObjC call/message targets.
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.
clang::GlobalDecl curGD
The GlobalDecl for the current function being compiled or the global variable currently being initial...
CIRGenTypes & getTypes() const
Address emitPointerWithAlignment(const clang::Expr *expr, LValueBaseInfo *baseInfo=nullptr)
Given an expression with a pointer type, emit the value and compute our best estimate of the alignmen...
const clang::LangOptions & getLangOpts() const
cir::AllocaOp createTempAlloca(mlir::Type ty, mlir::Location loc, const Twine &name="tmp", mlir::Value arraySize=nullptr, bool insertIntoFnEntryBlock=false)
This creates an alloca and inserts it into the entry block if ArraySize is nullptr,...
RValue emitCXXMemberPointerCallExpr(const CXXMemberCallExpr *ce, ReturnValueSlot returnValue)
bool isInConditionalBranch() const
void emitDeleteCall(const FunctionDecl *deleteFD, mlir::Value ptr, QualType deleteTy)
LValue emitLValue(const clang::Expr *e)
Emit code to compute a designator that specifies the location of the expression.
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
RValue emitCXXMemberOrOperatorCall(const clang::CXXMethodDecl *md, const CIRGenCallee &callee, ReturnValueSlot returnValue, mlir::Value thisPtr, mlir::Value implicitParam, clang::QualType implicitParamTy, const clang::CallExpr *ce, CallArgList *rtlArgs)
void emitNullInitialization(mlir::Location loc, Address destPtr, QualType ty)
RValue emitCUDAKernelCallExpr(const CUDAKernelCallExpr *expr, ReturnValueSlot returnValue)
EHScopeStack ehStack
Tracks function scope overall cleanup handling.
void emitNewArrayInitializer(const CXXNewExpr *e, QualType elementType, mlir::Type elementTy, Address beginPtr, mlir::Value numElements, mlir::Value allocSizeWithoutCookie)
clang::SanitizerSet sanOpts
Sanitizers enabled for this function.
mlir::Value emitCXXTypeidExpr(const CXXTypeidExpr *e)
mlir::Type convertTypeForMem(QualType t)
void emitCXXConstructExpr(const clang::CXXConstructExpr *e, AggValueSlot dest)
mlir::Value emitCXXNewExpr(const CXXNewExpr *e)
Address returnValue
The temporary alloca to hold the return value.
void emitCXXConstructorCall(const clang::CXXConstructorDecl *d, clang::CXXCtorType type, bool forVirtualBase, bool delegating, AggValueSlot thisAVS, const clang::CXXConstructExpr *e)
void emitScalarInit(const clang::Expr *init, mlir::Location loc, LValue lvalue, bool capturedByInit=false)
RValue emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, const CallArgList &args, cir::CIRCallOpInterface *callOp, mlir::Location loc)
void deactivateCleanupBlock(EHScopeStack::stable_iterator cleanup, mlir::Operation *dominatingIP)
Deactivates the given cleanup block.
mlir::Value emitScalarExpr(const clang::Expr *e, bool ignoreResultAssign=false)
Emit the computation of the specified expression of scalar type.
CIRGenBuilderTy & getBuilder()
void emitComplexExprIntoLValue(const Expr *e, LValue dest, bool isInit)
LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)
void emitCXXDestructorCall(const CXXDestructorDecl *dd, CXXDtorType type, bool forVirtualBase, bool delegating, Address thisAddr, QualType thisTy)
RValue emitNewOrDeleteBuiltinCall(const FunctionProtoType *type, const CallExpr *callExpr, OverloadedOperatorKind op)
void emitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, const clang::ArrayType *arrayType, Address arrayBegin, const CXXConstructExpr *e, bool newPointerIsChecked, bool zeroInitialize=false)
Emit a loop to call a particular constructor for each of several members of an array.
std::optional< mlir::Location > currSrcLoc
Use to track source locations across nested visitor traversals.
clang::ASTContext & getContext() const
RValue emitCXXMemberOrOperatorMemberCallExpr(const clang::CallExpr *ce, const clang::CXXMethodDecl *md, ReturnValueSlot returnValue, bool hasQualifier, clang::NestedNameSpecifier qualifier, bool isArrow, const clang::Expr *base)
void emitCXXDeleteExpr(const CXXDeleteExpr *e)
RValue emitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *e, const CXXMethodDecl *md, ReturnValueSlot returnValue)
void emitIgnoredExpr(const clang::Expr *e)
Emit code to compute the specified expression, ignoring the result.
mlir::Value emitDynamicCast(Address thisAddr, const CXXDynamicCastExpr *dce)
void emitAggExpr(const clang::Expr *e, AggValueSlot slot)
RValue emitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *expr)
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
mlir::TypedAttr emitNullConstantForBase(const CXXRecordDecl *record)
Return a null constant appropriate for zero-initializing a base class with the given type.
cir::FuncOp getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType=nullptr, bool forVTable=false, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
Return the address of the given function.
const cir::CIRDataLayout getDataLayout() const
CIRGenCXXABI & getCXXABI() const
const CIRGenFunctionInfo & arrangeFreeFunctionCall(const CallArgList &args, const FunctionType *fnType)
clang::CanQualType deriveThisType(const clang::CXXRecordDecl *rd, const clang::CXXMethodDecl *md)
Derives the 'this' type for CIRGen purposes, i.e.
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
void add(RValue rvalue, clang::QualType type)
mlir::Attribute tryEmitAbstract(const Expr *e, QualType destType)
Information for lazily generating a cleanup.
A saved depth on the scope stack.
T * pushCleanupWithExtra(CleanupKind kind, size_t n, As... a)
Push a cleanup with non-constant storage requirements on the stack.
AlignmentSource getAlignmentSource() const
Address getAddress() const
mlir::Value getPointer() const
void setAddress(Address address)
This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(mlir::Value v)
mlir::Value getValue() const
Return the value of this scalar value.
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...
Represents a call to a CUDA kernel function.
Represents a call to a C++ constructor.
bool isElidable() const
Whether this construction is elidable.
Expr * getArg(unsigned Arg)
Return the specified argument.
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
CXXConstructionKind getConstructionKind() const
Determine whether this constructor is actually constructing a base class (rather than a complete obje...
Represents a C++ constructor within a class.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Represents a delete expression for memory deallocation and destructor calls, e.g.
FunctionDecl * getOperatorDelete() const
QualType getDestroyedType() const
Retrieve the type being destroyed.
Represents a C++ destructor within a class.
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
bool isAlwaysNull() const
isAlwaysNull - Return whether the result of the dynamic_cast is proven to always be null.
Represents a call to a member function that may be written either with member call syntax (e....
SourceLocation getExprLoc() const LLVM_READONLY
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
llvm::iterator_range< arg_iterator > placement_arguments()
QualType getAllocatedType() const
unsigned getNumImplicitArgs() const
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
ImplicitAllocationParameters implicitAllocationParameters() const
Provides the full set of information about expected implicit parameters in this call.
bool hasInitializer() const
Whether this new-expression has any initializer at all.
bool shouldNullCheckAllocation() const
True if the allocation result needs to be null-checked.
bool passAlignment() const
Indicates whether the required alignment should be implicitly passed to the allocation function.
FunctionDecl * getOperatorDelete() const
unsigned getNumPlacementArgs() const
SourceRange getSourceRange() const
FunctionDecl * getOperatorNew() const
Expr * getInitializer()
The initializer of this new-expression.
A call to an overloaded operator written using operator syntax.
Represents a list-initialization with parenthesis.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
Represents a C++ struct/union/class.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
bool isTypeOperand() const
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Expr * getExprOperand() const
SourceRange getSourceRange() const LLVM_READONLY
bool isMostDerived(const ASTContext &Context) const
Best-effort check if the expression operand refers to a most derived object.
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr....
bool hasNullCheck() const
Whether this is of a form like "typeid(*ptr)" that can throw a std::bad_typeid if a pointer is a null...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isOne() const
isOne - Test whether the quantity equals one.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Represents the canonical version of C arrays with a specified constant size.
The results of name lookup within a DeclContext.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
The name of a declaration.
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
This represents one expression.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a function declaration or definition.
bool isDestroyingOperatorDelete() const
Determine whether this is a destroying operator delete.
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
bool isReplaceableGlobalAllocationFunction(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
UsualDeleteParams getUsualDeleteParams() const
bool isReservedGlobalPlacementOperator() const
Determines whether this operator new or delete is one of the reserved global placement operators: voi...
bool isDefaulted() const
Whether this function is defaulted.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Represents a prototype with parameter type info, e.g.
CanThrowResult canThrow() const
Determine whether this function type has a non-throwing exception specification.
GlobalDecl - represents a global declaration.
const Decl * getDecl() const
Describes an C or C++ initializer list.
bool isStringLiteralInit() const
Is this an initializer for an array of characters, initialized by a string literal or an @encode?
unsigned getNumInits() const
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
ArrayRef< Expr * > inits()
A pointer to member type per C++ 8.3.3 - Pointers to members.
QualType getPointeeType() const
This represents a decl that may have a name.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
ObjCEncodeExpr, used for @encode in Objective-C.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
bool isPODType(const ASTContext &Context) const
Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
bool hasStrongOrWeakObjCLifetime() const
Base for LValueReferenceType and RValueReferenceType.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
StringLiteral - This represents a string literal expression, e.g.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Exposes information about the current target.
unsigned getNewAlign() const
Return the largest alignment for which a suitably-sized allocation with 'operator new(size_t)' is gua...
SourceLocation getBeginLoc() const LLVM_READONLY
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
bool isVoidPointerType() const
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
const internal::VariadicDynCastAllOfMatcher< Stmt, CallExpr > callExpr
Matches call expressions.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
AlignedAllocationMode alignedAllocationModeFromBool(bool IsAligned)
bool isAlignedAllocation(AlignedAllocationMode Mode)
@ Dtor_Complete
Complete object dtor.
bool isTypeAwareAllocation(TypeAwareAllocationMode Mode)
U cast(CodeGen::Address addr)
__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)
static bool objCLifetime()
static bool addressSpace()
static bool devirtualizeDestructor()
static bool aggValueSlotGC()
static bool devirtualizeMemberFunction()
static bool deleteArray()
static bool emitTypeCheck()
static bool cleanupDeactivationScope()
static bool opCallMustTail()
static bool typeAwareAllocation()
static bool exprNewNullCheck()
static bool emitNullCheckForDeleteCalls()
static bool generateDebugInfo()
clang::CharUnits getSizeAlign() const
The parameters to pass to a usual operator delete.
TypeAwareAllocationMode TypeAwareDelete
AlignedAllocationMode Alignment