1034 lines · cpp
1//===--- CIRGenExprCXX.cpp - Emit CIR Code for C++ expressions ------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This contains code dealing with code generation of C++ expressions10//11//===----------------------------------------------------------------------===//12 13#include "CIRGenCXXABI.h"14#include "CIRGenConstantEmitter.h"15#include "CIRGenFunction.h"16 17#include "clang/AST/DeclCXX.h"18#include "clang/AST/ExprCXX.h"19#include "clang/Basic/OperatorKinds.h"20#include "clang/CIR/MissingFeatures.h"21 22using namespace clang;23using namespace clang::CIRGen;24 25namespace {26struct MemberCallInfo {27 RequiredArgs reqArgs;28 // Number of prefix arguments for the call. Ignores the `this` pointer.29 unsigned prefixSize;30};31} // namespace32 33static MemberCallInfo commonBuildCXXMemberOrOperatorCall(34 CIRGenFunction &cgf, const CXXMethodDecl *md, mlir::Value thisPtr,35 mlir::Value implicitParam, QualType implicitParamTy, const CallExpr *ce,36 CallArgList &args, CallArgList *rtlArgs) {37 assert(ce == nullptr || isa<CXXMemberCallExpr>(ce) ||38 isa<CXXOperatorCallExpr>(ce));39 assert(md->isInstance() &&40 "Trying to emit a member or operator call expr on a static method!");41 42 // Push the this ptr.43 const CXXRecordDecl *rd =44 cgf.cgm.getCXXABI().getThisArgumentTypeForMethod(md);45 args.add(RValue::get(thisPtr), cgf.getTypes().deriveThisType(rd, md));46 47 // If there is an implicit parameter (e.g. VTT), emit it.48 if (implicitParam) {49 args.add(RValue::get(implicitParam), implicitParamTy);50 }51 52 const auto *fpt = md->getType()->castAs<FunctionProtoType>();53 RequiredArgs required =54 RequiredArgs::getFromProtoWithExtraSlots(fpt, args.size());55 unsigned prefixSize = args.size() - 1;56 57 // Add the rest of the call args58 if (rtlArgs) {59 // Special case: if the caller emitted the arguments right-to-left already60 // (prior to emitting the *this argument), we're done. This happens for61 // assignment operators.62 args.addFrom(*rtlArgs);63 } else if (ce) {64 // Special case: skip first argument of CXXOperatorCall (it is "this").65 unsigned argsToSkip = isa<CXXOperatorCallExpr>(ce) ? 1 : 0;66 cgf.emitCallArgs(args, fpt, drop_begin(ce->arguments(), argsToSkip),67 ce->getDirectCallee());68 } else {69 assert(70 fpt->getNumParams() == 0 &&71 "No CallExpr specified for function with non-zero number of arguments");72 }73 74 // return {required, prefixSize};75 return {required, prefixSize};76}77 78RValue CIRGenFunction::emitCXXMemberOrOperatorMemberCallExpr(79 const CallExpr *ce, const CXXMethodDecl *md, ReturnValueSlot returnValue,80 bool hasQualifier, NestedNameSpecifier qualifier, bool isArrow,81 const Expr *base) {82 assert(isa<CXXMemberCallExpr>(ce) || isa<CXXOperatorCallExpr>(ce));83 84 // Compute the object pointer.85 bool canUseVirtualCall = md->isVirtual() && !hasQualifier;86 const CXXMethodDecl *devirtualizedMethod = nullptr;87 assert(!cir::MissingFeatures::devirtualizeMemberFunction());88 89 // Note on trivial assignment90 // --------------------------91 // Classic codegen avoids generating the trivial copy/move assignment operator92 // when it isn't necessary, choosing instead to just produce IR with an93 // equivalent effect. We have chosen not to do that in CIR, instead emitting94 // trivial copy/move assignment operators and allowing later transformations95 // to optimize them away if appropriate.96 97 // C++17 demands that we evaluate the RHS of a (possibly-compound) assignment98 // operator before the LHS.99 CallArgList rtlArgStorage;100 CallArgList *rtlArgs = nullptr;101 if (auto *oce = dyn_cast<CXXOperatorCallExpr>(ce)) {102 if (oce->isAssignmentOp()) {103 rtlArgs = &rtlArgStorage;104 emitCallArgs(*rtlArgs, md->getType()->castAs<FunctionProtoType>(),105 drop_begin(ce->arguments(), 1), ce->getDirectCallee(),106 /*ParamsToSkip*/ 0);107 }108 }109 110 LValue thisPtr;111 if (isArrow) {112 LValueBaseInfo baseInfo;113 assert(!cir::MissingFeatures::opTBAA());114 Address thisValue = emitPointerWithAlignment(base, &baseInfo);115 thisPtr = makeAddrLValue(thisValue, base->getType(), baseInfo);116 } else {117 thisPtr = emitLValue(base);118 }119 120 if (isa<CXXConstructorDecl>(md)) {121 cgm.errorNYI(ce->getSourceRange(),122 "emitCXXMemberOrOperatorMemberCallExpr: constructor call");123 return RValue::get(nullptr);124 }125 126 if ((md->isTrivial() || (md->isDefaulted() && md->getParent()->isUnion())) &&127 isa<CXXDestructorDecl>(md))128 return RValue::get(nullptr);129 130 // Compute the function type we're calling131 const CXXMethodDecl *calleeDecl =132 devirtualizedMethod ? devirtualizedMethod : md;133 const CIRGenFunctionInfo *fInfo = nullptr;134 if (const auto *dtor = dyn_cast<CXXDestructorDecl>(calleeDecl))135 fInfo = &cgm.getTypes().arrangeCXXStructorDeclaration(136 GlobalDecl(dtor, Dtor_Complete));137 else138 fInfo = &cgm.getTypes().arrangeCXXMethodDeclaration(calleeDecl);139 140 cir::FuncType ty = cgm.getTypes().getFunctionType(*fInfo);141 142 assert(!cir::MissingFeatures::sanitizers());143 assert(!cir::MissingFeatures::emitTypeCheck());144 145 // C++ [class.virtual]p12:146 // Explicit qualification with the scope operator (5.1) suppresses the147 // virtual call mechanism.148 //149 // We also don't emit a virtual call if the base expression has a record type150 // because then we know what the type is.151 bool useVirtualCall = canUseVirtualCall && !devirtualizedMethod;152 153 if (const auto *dtor = dyn_cast<CXXDestructorDecl>(calleeDecl)) {154 assert(ce->arg_begin() == ce->arg_end() &&155 "Destructor shouldn't have explicit parameters");156 assert(returnValue.isNull() && "Destructor shouldn't have return value");157 if (useVirtualCall) {158 cgm.getCXXABI().emitVirtualDestructorCall(*this, dtor, Dtor_Complete,159 thisPtr.getAddress(),160 cast<CXXMemberCallExpr>(ce));161 } else {162 GlobalDecl globalDecl(dtor, Dtor_Complete);163 CIRGenCallee callee;164 assert(!cir::MissingFeatures::appleKext());165 if (!devirtualizedMethod) {166 callee = CIRGenCallee::forDirect(167 cgm.getAddrOfCXXStructor(globalDecl, fInfo, ty), globalDecl);168 } else {169 cgm.errorNYI(ce->getSourceRange(), "devirtualized destructor call");170 return RValue::get(nullptr);171 }172 173 QualType thisTy =174 isArrow ? base->getType()->getPointeeType() : base->getType();175 // CIRGen does not pass CallOrInvoke here (different from OG LLVM codegen)176 // because in practice it always null even in OG.177 emitCXXDestructorCall(globalDecl, callee, thisPtr.getPointer(), thisTy,178 /*implicitParam=*/nullptr,179 /*implicitParamTy=*/QualType(), ce);180 }181 return RValue::get(nullptr);182 }183 184 CIRGenCallee callee;185 if (useVirtualCall) {186 callee = CIRGenCallee::forVirtual(ce, md, thisPtr.getAddress(), ty);187 } else {188 assert(!cir::MissingFeatures::sanitizers());189 if (getLangOpts().AppleKext) {190 cgm.errorNYI(ce->getSourceRange(),191 "emitCXXMemberOrOperatorMemberCallExpr: AppleKext");192 return RValue::get(nullptr);193 }194 195 callee = CIRGenCallee::forDirect(cgm.getAddrOfFunction(calleeDecl, ty),196 GlobalDecl(calleeDecl));197 }198 199 if (md->isVirtual()) {200 Address newThisAddr =201 cgm.getCXXABI().adjustThisArgumentForVirtualFunctionCall(202 *this, calleeDecl, thisPtr.getAddress(), useVirtualCall);203 thisPtr.setAddress(newThisAddr);204 }205 206 return emitCXXMemberOrOperatorCall(207 calleeDecl, callee, returnValue, thisPtr.getPointer(),208 /*ImplicitParam=*/nullptr, QualType(), ce, rtlArgs);209}210 211RValue212CIRGenFunction::emitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *e,213 const CXXMethodDecl *md,214 ReturnValueSlot returnValue) {215 assert(md->isInstance() &&216 "Trying to emit a member call expr on a static method!");217 return emitCXXMemberOrOperatorMemberCallExpr(218 e, md, returnValue, /*HasQualifier=*/false, /*Qualifier=*/std::nullopt,219 /*IsArrow=*/false, e->getArg(0));220}221 222RValue CIRGenFunction::emitCXXMemberOrOperatorCall(223 const CXXMethodDecl *md, const CIRGenCallee &callee,224 ReturnValueSlot returnValue, mlir::Value thisPtr, mlir::Value implicitParam,225 QualType implicitParamTy, const CallExpr *ce, CallArgList *rtlArgs) {226 const auto *fpt = md->getType()->castAs<FunctionProtoType>();227 CallArgList args;228 MemberCallInfo callInfo = commonBuildCXXMemberOrOperatorCall(229 *this, md, thisPtr, implicitParam, implicitParamTy, ce, args, rtlArgs);230 auto &fnInfo = cgm.getTypes().arrangeCXXMethodCall(231 args, fpt, callInfo.reqArgs, callInfo.prefixSize);232 assert((ce || currSrcLoc) && "expected source location");233 mlir::Location loc = ce ? getLoc(ce->getExprLoc()) : *currSrcLoc;234 assert(!cir::MissingFeatures::opCallMustTail());235 return emitCall(fnInfo, callee, returnValue, args, nullptr, loc);236}237 238static void emitNullBaseClassInitialization(CIRGenFunction &cgf,239 Address destPtr,240 const CXXRecordDecl *base) {241 if (base->isEmpty())242 return;243 244 const ASTRecordLayout &layout = cgf.getContext().getASTRecordLayout(base);245 CharUnits nvSize = layout.getNonVirtualSize();246 247 // We cannot simply zero-initialize the entire base sub-object if vbptrs are248 // present, they are initialized by the most derived class before calling the249 // constructor.250 SmallVector<std::pair<CharUnits, CharUnits>, 1> stores;251 stores.emplace_back(CharUnits::Zero(), nvSize);252 253 // Each store is split by the existence of a vbptr.254 // TODO(cir): This only needs handling for the MS CXXABI.255 assert(!cir::MissingFeatures::msabi());256 257 // If the type contains a pointer to data member we can't memset it to zero.258 // Instead, create a null constant and copy it to the destination.259 // TODO: there are other patterns besides zero that we can usefully memset,260 // like -1, which happens to be the pattern used by member-pointers.261 // TODO: isZeroInitializable can be over-conservative in the case where a262 // virtual base contains a member pointer.263 mlir::TypedAttr nullConstantForBase = cgf.cgm.emitNullConstantForBase(base);264 if (!cgf.getBuilder().isNullValue(nullConstantForBase)) {265 cgf.cgm.errorNYI(266 base->getSourceRange(),267 "emitNullBaseClassInitialization: base constant is not null");268 } else {269 // Otherwise, just memset the whole thing to zero. This is legal270 // because in LLVM, all default initializers (other than the ones we just271 // handled above) are guaranteed to have a bit pattern of all zeros.272 // TODO(cir): When the MS CXXABI is supported, we will need to iterate over273 // `stores` and create a separate memset for each one. For now, we know that274 // there will only be one store and it will begin at offset zero, so that275 // simplifies this code considerably.276 assert(stores.size() == 1 && "Expected only one store");277 assert(stores[0].first == CharUnits::Zero() &&278 "Expected store to begin at offset zero");279 CIRGenBuilderTy builder = cgf.getBuilder();280 mlir::Location loc = cgf.getLoc(base->getBeginLoc());281 builder.createStore(loc, builder.getConstant(loc, nullConstantForBase),282 destPtr);283 }284}285 286void CIRGenFunction::emitCXXConstructExpr(const CXXConstructExpr *e,287 AggValueSlot dest) {288 assert(!dest.isIgnored() && "Must have a destination!");289 const CXXConstructorDecl *cd = e->getConstructor();290 291 // If we require zero initialization before (or instead of) calling the292 // constructor, as can be the case with a non-user-provided default293 // constructor, emit the zero initialization now, unless destination is294 // already zeroed.295 if (e->requiresZeroInitialization() && !dest.isZeroed()) {296 switch (e->getConstructionKind()) {297 case CXXConstructionKind::Delegating:298 case CXXConstructionKind::Complete:299 emitNullInitialization(getLoc(e->getSourceRange()), dest.getAddress(),300 e->getType());301 break;302 case CXXConstructionKind::VirtualBase:303 case CXXConstructionKind::NonVirtualBase:304 emitNullBaseClassInitialization(*this, dest.getAddress(),305 cd->getParent());306 break;307 }308 }309 310 // If this is a call to a trivial default constructor, do nothing.311 if (cd->isTrivial() && cd->isDefaultConstructor())312 return;313 314 // Elide the constructor if we're constructing from a temporary315 if (getLangOpts().ElideConstructors && e->isElidable()) {316 // FIXME: This only handles the simplest case, where the source object is317 // passed directly as the first argument to the constructor. This318 // should also handle stepping through implicit casts and conversion319 // sequences which involve two steps, with a conversion operator320 // follwed by a converting constructor.321 const Expr *srcObj = e->getArg(0);322 assert(srcObj->isTemporaryObject(getContext(), cd->getParent()));323 assert(324 getContext().hasSameUnqualifiedType(e->getType(), srcObj->getType()));325 emitAggExpr(srcObj, dest);326 return;327 }328 329 if (const ArrayType *arrayType = getContext().getAsArrayType(e->getType())) {330 assert(!cir::MissingFeatures::sanitizers());331 emitCXXAggrConstructorCall(cd, arrayType, dest.getAddress(), e, false);332 } else {333 334 clang::CXXCtorType type = Ctor_Complete;335 bool forVirtualBase = false;336 bool delegating = false;337 338 switch (e->getConstructionKind()) {339 case CXXConstructionKind::Complete:340 type = Ctor_Complete;341 break;342 case CXXConstructionKind::Delegating:343 // We should be emitting a constructor; GlobalDecl will assert this344 type = curGD.getCtorType();345 delegating = true;346 break;347 case CXXConstructionKind::VirtualBase:348 forVirtualBase = true;349 [[fallthrough]];350 case CXXConstructionKind::NonVirtualBase:351 type = Ctor_Base;352 break;353 }354 355 emitCXXConstructorCall(cd, type, forVirtualBase, delegating, dest, e);356 }357}358 359static CharUnits calculateCookiePadding(CIRGenFunction &cgf,360 const CXXNewExpr *e) {361 if (!e->isArray())362 return CharUnits::Zero();363 364 // No cookie is required if the operator new[] being used is the365 // reserved placement operator new[].366 if (e->getOperatorNew()->isReservedGlobalPlacementOperator())367 return CharUnits::Zero();368 369 return cgf.cgm.getCXXABI().getArrayCookieSize(e);370}371 372static mlir::Value emitCXXNewAllocSize(CIRGenFunction &cgf, const CXXNewExpr *e,373 unsigned minElements,374 mlir::Value &numElements,375 mlir::Value &sizeWithoutCookie) {376 QualType type = e->getAllocatedType();377 mlir::Location loc = cgf.getLoc(e->getSourceRange());378 379 if (!e->isArray()) {380 CharUnits typeSize = cgf.getContext().getTypeSizeInChars(type);381 sizeWithoutCookie = cgf.getBuilder().getConstant(382 loc, cir::IntAttr::get(cgf.sizeTy, typeSize.getQuantity()));383 return sizeWithoutCookie;384 }385 386 // The width of size_t.387 unsigned sizeWidth = cgf.cgm.getDataLayout().getTypeSizeInBits(cgf.sizeTy);388 389 // The number of elements can be have an arbitrary integer type;390 // essentially, we need to multiply it by a constant factor, add a391 // cookie size, and verify that the result is representable as a392 // size_t. That's just a gloss, though, and it's wrong in one393 // important way: if the count is negative, it's an error even if394 // the cookie size would bring the total size >= 0.395 //396 // If the array size is constant, Sema will have prevented negative397 // values and size overflow.398 399 // Compute the constant factor.400 llvm::APInt arraySizeMultiplier(sizeWidth, 1);401 while (const ConstantArrayType *cat =402 cgf.getContext().getAsConstantArrayType(type)) {403 type = cat->getElementType();404 arraySizeMultiplier *= cat->getSize();405 }406 407 CharUnits typeSize = cgf.getContext().getTypeSizeInChars(type);408 llvm::APInt typeSizeMultiplier(sizeWidth, typeSize.getQuantity());409 typeSizeMultiplier *= arraySizeMultiplier;410 411 // Figure out the cookie size.412 llvm::APInt cookieSize(sizeWidth,413 calculateCookiePadding(cgf, e).getQuantity());414 415 // This will be a size_t.416 mlir::Value size;417 418 // Emit the array size expression.419 // We multiply the size of all dimensions for NumElements.420 // e.g for 'int[2][3]', ElemType is 'int' and NumElements is 6.421 const Expr *arraySize = *e->getArraySize();422 mlir::Attribute constNumElements =423 ConstantEmitter(cgf.cgm, &cgf)424 .emitAbstract(arraySize, arraySize->getType());425 if (constNumElements) {426 // Get an APInt from the constant427 const llvm::APInt &count =428 mlir::cast<cir::IntAttr>(constNumElements).getValue();429 430 [[maybe_unused]] unsigned numElementsWidth = count.getBitWidth();431 bool hasAnyOverflow = false;432 433 // The equivalent code in CodeGen/CGExprCXX.cpp handles these cases as434 // overflow, but that should never happen. The size argument is implicitly435 // cast to a size_t, so it can never be negative and numElementsWidth will436 // always equal sizeWidth.437 assert(!count.isNegative() && "Expected non-negative array size");438 assert(numElementsWidth == sizeWidth &&439 "Expected a size_t array size constant");440 441 // Okay, compute a count at the right width.442 llvm::APInt adjustedCount = count.zextOrTrunc(sizeWidth);443 444 // Scale numElements by that. This might overflow, but we don't445 // care because it only overflows if allocationSize does too, and446 // if that overflows then we shouldn't use this.447 // This emits a constant that may not be used, but we can't tell here448 // whether it will be needed or not.449 numElements =450 cgf.getBuilder().getConstInt(loc, adjustedCount * arraySizeMultiplier);451 452 // Compute the size before cookie, and track whether it overflowed.453 bool overflow;454 llvm::APInt allocationSize =455 adjustedCount.umul_ov(typeSizeMultiplier, overflow);456 457 // Sema prevents us from hitting this case458 assert(!overflow && "Overflow in array allocation size");459 460 // Add in the cookie, and check whether it's overflowed.461 if (cookieSize != 0) {462 // Save the current size without a cookie. This shouldn't be463 // used if there was overflow464 sizeWithoutCookie = cgf.getBuilder().getConstInt(465 loc, allocationSize.zextOrTrunc(sizeWidth));466 467 allocationSize = allocationSize.uadd_ov(cookieSize, overflow);468 hasAnyOverflow |= overflow;469 }470 471 // On overflow, produce a -1 so operator new will fail472 if (hasAnyOverflow) {473 size =474 cgf.getBuilder().getConstInt(loc, llvm::APInt::getAllOnes(sizeWidth));475 } else {476 size = cgf.getBuilder().getConstInt(loc, allocationSize);477 }478 } else {479 // TODO: Handle the variable size case480 cgf.cgm.errorNYI(e->getSourceRange(),481 "emitCXXNewAllocSize: variable array size");482 }483 484 if (cookieSize == 0)485 sizeWithoutCookie = size;486 else487 assert(sizeWithoutCookie && "didn't set sizeWithoutCookie?");488 489 return size;490}491 492static void storeAnyExprIntoOneUnit(CIRGenFunction &cgf, const Expr *init,493 QualType allocType, Address newPtr,494 AggValueSlot::Overlap_t mayOverlap) {495 // FIXME: Refactor with emitExprAsInit.496 switch (cgf.getEvaluationKind(allocType)) {497 case cir::TEK_Scalar:498 cgf.emitScalarInit(init, cgf.getLoc(init->getSourceRange()),499 cgf.makeAddrLValue(newPtr, allocType), false);500 return;501 case cir::TEK_Complex:502 cgf.emitComplexExprIntoLValue(init, cgf.makeAddrLValue(newPtr, allocType),503 /*isInit*/ true);504 return;505 case cir::TEK_Aggregate: {506 assert(!cir::MissingFeatures::aggValueSlotGC());507 assert(!cir::MissingFeatures::sanitizers());508 AggValueSlot slot = AggValueSlot::forAddr(509 newPtr, allocType.getQualifiers(), AggValueSlot::IsDestructed,510 AggValueSlot::IsNotAliased, mayOverlap, AggValueSlot::IsNotZeroed);511 cgf.emitAggExpr(init, slot);512 return;513 }514 }515 llvm_unreachable("bad evaluation kind");516}517 518void CIRGenFunction::emitNewArrayInitializer(519 const CXXNewExpr *e, QualType elementType, mlir::Type elementTy,520 Address beginPtr, mlir::Value numElements,521 mlir::Value allocSizeWithoutCookie) {522 // If we have a type with trivial initialization and no initializer,523 // there's nothing to do.524 if (!e->hasInitializer())525 return;526 527 unsigned initListElements = 0;528 529 const Expr *init = e->getInitializer();530 const InitListExpr *ile = dyn_cast<InitListExpr>(init);531 if (ile) {532 cgm.errorNYI(ile->getSourceRange(), "emitNewArrayInitializer: init list");533 return;534 }535 536 // If all elements have already been initialized, skip any further537 // initialization.538 auto constOp = mlir::dyn_cast<cir::ConstantOp>(numElements.getDefiningOp());539 if (constOp) {540 auto constIntAttr = mlir::dyn_cast<cir::IntAttr>(constOp.getValue());541 // Just skip out if the constant count is zero.542 if (constIntAttr && constIntAttr.getUInt() <= initListElements)543 return;544 }545 546 assert(init && "have trailing elements to initialize but no initializer");547 548 // If this is a constructor call, try to optimize it out, and failing that549 // emit a single loop to initialize all remaining elements.550 if (const CXXConstructExpr *cce = dyn_cast<CXXConstructExpr>(init)) {551 CXXConstructorDecl *ctor = cce->getConstructor();552 if (ctor->isTrivial()) {553 // If new expression did not specify value-initialization, then there554 // is no initialization.555 if (!cce->requiresZeroInitialization())556 return;557 558 cgm.errorNYI(cce->getSourceRange(),559 "emitNewArrayInitializer: trivial ctor zero-init");560 return;561 }562 563 cgm.errorNYI(cce->getSourceRange(),564 "emitNewArrayInitializer: ctor initializer");565 return;566 }567 568 cgm.errorNYI(init->getSourceRange(),569 "emitNewArrayInitializer: unsupported initializer");570 return;571}572 573static void emitNewInitializer(CIRGenFunction &cgf, const CXXNewExpr *e,574 QualType elementType, mlir::Type elementTy,575 Address newPtr, mlir::Value numElements,576 mlir::Value allocSizeWithoutCookie) {577 assert(!cir::MissingFeatures::generateDebugInfo());578 if (e->isArray()) {579 cgf.emitNewArrayInitializer(e, elementType, elementTy, newPtr, numElements,580 allocSizeWithoutCookie);581 } else if (const Expr *init = e->getInitializer()) {582 storeAnyExprIntoOneUnit(cgf, init, e->getAllocatedType(), newPtr,583 AggValueSlot::DoesNotOverlap);584 }585}586 587RValue CIRGenFunction::emitCXXDestructorCall(588 GlobalDecl dtor, const CIRGenCallee &callee, mlir::Value thisVal,589 QualType thisTy, mlir::Value implicitParam, QualType implicitParamTy,590 const CallExpr *ce) {591 const CXXMethodDecl *dtorDecl = cast<CXXMethodDecl>(dtor.getDecl());592 593 assert(!thisTy.isNull());594 assert(thisTy->getAsCXXRecordDecl() == dtorDecl->getParent() &&595 "Pointer/Object mixup");596 597 assert(!cir::MissingFeatures::addressSpace());598 599 CallArgList args;600 commonBuildCXXMemberOrOperatorCall(*this, dtorDecl, thisVal, implicitParam,601 implicitParamTy, ce, args, nullptr);602 assert((ce || dtor.getDecl()) && "expected source location provider");603 assert(!cir::MissingFeatures::opCallMustTail());604 return emitCall(cgm.getTypes().arrangeCXXStructorDeclaration(dtor), callee,605 ReturnValueSlot(), args, nullptr,606 ce ? getLoc(ce->getExprLoc())607 : getLoc(dtor.getDecl()->getSourceRange()));608}609 610RValue CIRGenFunction::emitCXXPseudoDestructorExpr(611 const CXXPseudoDestructorExpr *expr) {612 QualType destroyedType = expr->getDestroyedType();613 if (destroyedType.hasStrongOrWeakObjCLifetime()) {614 assert(!cir::MissingFeatures::objCLifetime());615 cgm.errorNYI(expr->getExprLoc(),616 "emitCXXPseudoDestructorExpr: Objective-C lifetime is NYI");617 } else {618 // C++ [expr.pseudo]p1:619 // The result shall only be used as the operand for the function call620 // operator (), and the result of such a call has type void. The only621 // effect is the evaluation of the postfix-expression before the dot or622 // arrow.623 emitIgnoredExpr(expr->getBase());624 }625 626 return RValue::get(nullptr);627}628 629/// Emit a call to an operator new or operator delete function, as implicitly630/// created by new-expressions and delete-expressions.631static RValue emitNewDeleteCall(CIRGenFunction &cgf,632 const FunctionDecl *calleeDecl,633 const FunctionProtoType *calleeType,634 const CallArgList &args) {635 cir::CIRCallOpInterface callOrTryCall;636 cir::FuncOp calleePtr = cgf.cgm.getAddrOfFunction(calleeDecl);637 CIRGenCallee callee =638 CIRGenCallee::forDirect(calleePtr, GlobalDecl(calleeDecl));639 RValue rv =640 cgf.emitCall(cgf.cgm.getTypes().arrangeFreeFunctionCall(args, calleeType),641 callee, ReturnValueSlot(), args, &callOrTryCall);642 643 /// C++1y [expr.new]p10:644 /// [In a new-expression,] an implementation is allowed to omit a call645 /// to a replaceable global allocation function.646 ///647 /// We model such elidable calls with the 'builtin' attribute.648 assert(!cir::MissingFeatures::attributeBuiltin());649 return rv;650}651 652RValue CIRGenFunction::emitNewOrDeleteBuiltinCall(const FunctionProtoType *type,653 const CallExpr *callExpr,654 OverloadedOperatorKind op) {655 CallArgList args;656 emitCallArgs(args, type, callExpr->arguments());657 // Find the allocation or deallocation function that we're calling.658 ASTContext &astContext = getContext();659 assert(op == OO_New || op == OO_Delete);660 DeclarationName name = astContext.DeclarationNames.getCXXOperatorName(op);661 662 clang::DeclContextLookupResult lookupResult =663 astContext.getTranslationUnitDecl()->lookup(name);664 for (const auto *decl : lookupResult) {665 if (const auto *funcDecl = dyn_cast<FunctionDecl>(decl)) {666 if (astContext.hasSameType(funcDecl->getType(), QualType(type, 0))) {667 if (sanOpts.has(SanitizerKind::AllocToken)) {668 // TODO: Set !alloc_token metadata.669 assert(!cir::MissingFeatures::allocToken());670 cgm.errorNYI("Alloc token sanitizer not yet supported!");671 }672 673 // Emit the call to operator new/delete.674 return emitNewDeleteCall(*this, funcDecl, type, args);675 }676 }677 }678 679 llvm_unreachable("predeclared global operator new/delete is missing");680}681 682namespace {683/// Calls the given 'operator delete' on a single object.684struct CallObjectDelete final : EHScopeStack::Cleanup {685 mlir::Value ptr;686 const FunctionDecl *operatorDelete;687 QualType elementType;688 689 CallObjectDelete(mlir::Value ptr, const FunctionDecl *operatorDelete,690 QualType elementType)691 : ptr(ptr), operatorDelete(operatorDelete), elementType(elementType) {}692 693 void emit(CIRGenFunction &cgf) override {694 cgf.emitDeleteCall(operatorDelete, ptr, elementType);695 }696};697} // namespace698 699/// Emit the code for deleting a single object.700static void emitObjectDelete(CIRGenFunction &cgf, const CXXDeleteExpr *de,701 Address ptr, QualType elementType) {702 // C++11 [expr.delete]p3:703 // If the static type of the object to be deleted is different from its704 // dynamic type, the static type shall be a base class of the dynamic type705 // of the object to be deleted and the static type shall have a virtual706 // destructor or the behavior is undefined.707 assert(!cir::MissingFeatures::emitTypeCheck());708 709 const FunctionDecl *operatorDelete = de->getOperatorDelete();710 assert(!operatorDelete->isDestroyingOperatorDelete());711 712 // Find the destructor for the type, if applicable. If the713 // destructor is virtual, we'll just emit the vcall and return.714 const CXXDestructorDecl *dtor = nullptr;715 if (const auto *rd = elementType->getAsCXXRecordDecl()) {716 if (rd->hasDefinition() && !rd->hasTrivialDestructor()) {717 dtor = rd->getDestructor();718 719 if (dtor->isVirtual()) {720 assert(!cir::MissingFeatures::devirtualizeDestructor());721 cgf.cgm.getCXXABI().emitVirtualObjectDelete(cgf, de, ptr, elementType,722 dtor);723 return;724 }725 }726 }727 728 // Make sure that we call delete even if the dtor throws.729 // This doesn't have to a conditional cleanup because we're going730 // to pop it off in a second.731 cgf.ehStack.pushCleanup<CallObjectDelete>(732 NormalAndEHCleanup, ptr.getPointer(), operatorDelete, elementType);733 734 if (dtor) {735 cgf.emitCXXDestructorCall(dtor, Dtor_Complete,736 /*ForVirtualBase=*/false,737 /*Delegating=*/false, ptr, elementType);738 } else if (elementType.getObjCLifetime()) {739 assert(!cir::MissingFeatures::objCLifetime());740 cgf.cgm.errorNYI(de->getSourceRange(), "emitObjectDelete: ObjCLifetime");741 }742 743 // In traditional LLVM codegen null checks are emitted to save a delete call.744 // In CIR we optimize for size by default, the null check should be added into745 // this function callers.746 assert(!cir::MissingFeatures::emitNullCheckForDeleteCalls());747 748 cgf.popCleanupBlock();749}750 751void CIRGenFunction::emitCXXDeleteExpr(const CXXDeleteExpr *e) {752 const Expr *arg = e->getArgument();753 Address ptr = emitPointerWithAlignment(arg);754 755 // Null check the pointer.756 //757 // We could avoid this null check if we can determine that the object758 // destruction is trivial and doesn't require an array cookie; we can759 // unconditionally perform the operator delete call in that case. For now, we760 // assume that deleted pointers are null rarely enough that it's better to761 // keep the branch. This might be worth revisiting for a -O0 code size win.762 //763 // CIR note: emit the code size friendly by default for now, such as mentioned764 // in `emitObjectDelete`.765 assert(!cir::MissingFeatures::emitNullCheckForDeleteCalls());766 QualType deleteTy = e->getDestroyedType();767 768 // A destroying operator delete overrides the entire operation of the769 // delete expression.770 if (e->getOperatorDelete()->isDestroyingOperatorDelete()) {771 cgm.errorNYI(e->getSourceRange(),772 "emitCXXDeleteExpr: destroying operator delete");773 return;774 }775 776 // We might be deleting a pointer to array.777 deleteTy = getContext().getBaseElementType(deleteTy);778 ptr = ptr.withElementType(builder, convertTypeForMem(deleteTy));779 780 if (e->isArrayForm()) {781 assert(!cir::MissingFeatures::deleteArray());782 cgm.errorNYI(e->getSourceRange(), "emitCXXDeleteExpr: array delete");783 return;784 } else {785 emitObjectDelete(*this, e, ptr, deleteTy);786 }787}788 789mlir::Value CIRGenFunction::emitCXXNewExpr(const CXXNewExpr *e) {790 // The element type being allocated.791 QualType allocType = getContext().getBaseElementType(e->getAllocatedType());792 793 // 1. Build a call to the allocation function.794 FunctionDecl *allocator = e->getOperatorNew();795 796 // If there is a brace-initializer, cannot allocate fewer elements than inits.797 unsigned minElements = 0;798 799 mlir::Value numElements = nullptr;800 mlir::Value allocSizeWithoutCookie = nullptr;801 mlir::Value allocSize = emitCXXNewAllocSize(802 *this, e, minElements, numElements, allocSizeWithoutCookie);803 CharUnits allocAlign = getContext().getTypeAlignInChars(allocType);804 805 // Emit the allocation call.806 Address allocation = Address::invalid();807 CallArgList allocatorArgs;808 if (allocator->isReservedGlobalPlacementOperator()) {809 // If the allocator is a global placement operator, just810 // "inline" it directly.811 assert(e->getNumPlacementArgs() == 1);812 const Expr *arg = *e->placement_arguments().begin();813 814 LValueBaseInfo baseInfo;815 allocation = emitPointerWithAlignment(arg, &baseInfo);816 817 // The pointer expression will, in many cases, be an opaque void*.818 // In these cases, discard the computed alignment and use the819 // formal alignment of the allocated type.820 if (baseInfo.getAlignmentSource() != AlignmentSource::Decl)821 allocation = allocation.withAlignment(allocAlign);822 823 // Set up allocatorArgs for the call to operator delete if it's not824 // the reserved global operator.825 if (e->getOperatorDelete() &&826 !e->getOperatorDelete()->isReservedGlobalPlacementOperator()) {827 cgm.errorNYI(e->getSourceRange(),828 "emitCXXNewExpr: reserved placement new with delete");829 }830 } else {831 const FunctionProtoType *allocatorType =832 allocator->getType()->castAs<FunctionProtoType>();833 unsigned paramsToSkip = 0;834 835 // The allocation size is the first argument.836 QualType sizeType = getContext().getSizeType();837 allocatorArgs.add(RValue::get(allocSize), sizeType);838 ++paramsToSkip;839 840 if (allocSize != allocSizeWithoutCookie) {841 CharUnits cookieAlign = getSizeAlign(); // FIXME: Ask the ABI.842 allocAlign = std::max(allocAlign, cookieAlign);843 }844 845 // The allocation alignment may be passed as the second argument.846 if (e->passAlignment()) {847 cgm.errorNYI(e->getSourceRange(), "emitCXXNewExpr: pass alignment");848 }849 850 // FIXME: Why do we not pass a CalleeDecl here?851 emitCallArgs(allocatorArgs, allocatorType, e->placement_arguments(),852 AbstractCallee(), paramsToSkip);853 RValue rv =854 emitNewDeleteCall(*this, allocator, allocatorType, allocatorArgs);855 856 // Set !heapallocsite metadata on the call to operator new.857 assert(!cir::MissingFeatures::generateDebugInfo());858 859 // If this was a call to a global replaceable allocation function that does860 // not take an alignment argument, the allocator is known to produce storage861 // that's suitably aligned for any object that fits, up to a known862 // threshold. Otherwise assume it's suitably aligned for the allocated type.863 CharUnits allocationAlign = allocAlign;864 if (!e->passAlignment() &&865 allocator->isReplaceableGlobalAllocationFunction()) {866 const TargetInfo &target = cgm.getASTContext().getTargetInfo();867 unsigned allocatorAlign = llvm::bit_floor(std::min<uint64_t>(868 target.getNewAlign(), getContext().getTypeSize(allocType)));869 allocationAlign = std::max(870 allocationAlign, getContext().toCharUnitsFromBits(allocatorAlign));871 }872 873 mlir::Value allocPtr = rv.getValue();874 allocation = Address(875 allocPtr, mlir::cast<cir::PointerType>(allocPtr.getType()).getPointee(),876 allocationAlign);877 }878 879 // Emit a null check on the allocation result if the allocation880 // function is allowed to return null (because it has a non-throwing881 // exception spec or is the reserved placement new) and we have an882 // interesting initializer will be running sanitizers on the initialization.883 bool nullCheck = e->shouldNullCheckAllocation() &&884 (!allocType.isPODType(getContext()) || e->hasInitializer());885 assert(!cir::MissingFeatures::exprNewNullCheck());886 if (nullCheck)887 cgm.errorNYI(e->getSourceRange(), "emitCXXNewExpr: null check");888 889 // If there's an operator delete, enter a cleanup to call it if an890 // exception is thrown.891 if (e->getOperatorDelete() &&892 !e->getOperatorDelete()->isReservedGlobalPlacementOperator())893 cgm.errorNYI(e->getSourceRange(), "emitCXXNewExpr: operator delete");894 895 if (allocSize != allocSizeWithoutCookie) {896 assert(e->isArray());897 allocation = cgm.getCXXABI().initializeArrayCookie(898 *this, allocation, numElements, e, allocType);899 }900 901 mlir::Type elementTy;902 if (e->isArray()) {903 // For array new, use the allocated type to handle multidimensional arrays904 // correctly905 elementTy = convertTypeForMem(e->getAllocatedType());906 } else {907 elementTy = convertTypeForMem(allocType);908 }909 Address result = builder.createElementBitCast(getLoc(e->getSourceRange()),910 allocation, elementTy);911 912 // Passing pointer through launder.invariant.group to avoid propagation of913 // vptrs information which may be included in previous type.914 // To not break LTO with different optimizations levels, we do it regardless915 // of optimization level.916 if (cgm.getCodeGenOpts().StrictVTablePointers &&917 allocator->isReservedGlobalPlacementOperator())918 cgm.errorNYI(e->getSourceRange(), "emitCXXNewExpr: strict vtable pointers");919 920 assert(!cir::MissingFeatures::sanitizers());921 922 emitNewInitializer(*this, e, allocType, elementTy, result, numElements,923 allocSizeWithoutCookie);924 return result.getPointer();925}926 927void CIRGenFunction::emitDeleteCall(const FunctionDecl *deleteFD,928 mlir::Value ptr, QualType deleteTy) {929 assert(!cir::MissingFeatures::deleteArray());930 931 const auto *deleteFTy = deleteFD->getType()->castAs<FunctionProtoType>();932 CallArgList deleteArgs;933 934 UsualDeleteParams params = deleteFD->getUsualDeleteParams();935 auto paramTypeIt = deleteFTy->param_type_begin();936 937 // Pass std::type_identity tag if present938 if (isTypeAwareAllocation(params.TypeAwareDelete))939 cgm.errorNYI(deleteFD->getSourceRange(),940 "emitDeleteCall: type aware delete");941 942 // Pass the pointer itself.943 QualType argTy = *paramTypeIt++;944 mlir::Value deletePtr =945 builder.createBitcast(ptr.getLoc(), ptr, convertType(argTy));946 deleteArgs.add(RValue::get(deletePtr), argTy);947 948 // Pass the std::destroying_delete tag if present.949 if (params.DestroyingDelete)950 cgm.errorNYI(deleteFD->getSourceRange(),951 "emitDeleteCall: destroying delete");952 953 // Pass the size if the delete function has a size_t parameter.954 if (params.Size) {955 QualType sizeType = *paramTypeIt++;956 CharUnits deleteTypeSize = getContext().getTypeSizeInChars(deleteTy);957 assert(mlir::isa<cir::IntType>(convertType(sizeType)) &&958 "expected cir::IntType");959 cir::ConstantOp size = builder.getConstInt(960 *currSrcLoc, convertType(sizeType), deleteTypeSize.getQuantity());961 962 deleteArgs.add(RValue::get(size), sizeType);963 }964 965 // Pass the alignment if the delete function has an align_val_t parameter.966 if (isAlignedAllocation(params.Alignment))967 cgm.errorNYI(deleteFD->getSourceRange(),968 "emitDeleteCall: aligned allocation");969 970 assert(paramTypeIt == deleteFTy->param_type_end() &&971 "unknown parameter to usual delete function");972 973 // Emit the call to delete.974 emitNewDeleteCall(*this, deleteFD, deleteFTy, deleteArgs);975}976 977static mlir::Value emitDynamicCastToNull(CIRGenFunction &cgf,978 mlir::Location loc, QualType destTy) {979 mlir::Type destCIRTy = cgf.convertType(destTy);980 assert(mlir::isa<cir::PointerType>(destCIRTy) &&981 "result of dynamic_cast should be a ptr");982 983 if (!destTy->isPointerType()) {984 mlir::Region *currentRegion = cgf.getBuilder().getBlock()->getParent();985 /// C++ [expr.dynamic.cast]p9:986 /// A failed cast to reference type throws std::bad_cast987 cgf.cgm.getCXXABI().emitBadCastCall(cgf, loc);988 989 // The call to bad_cast will terminate the current block. Create a new block990 // to hold any follow up code.991 cgf.getBuilder().createBlock(currentRegion, currentRegion->end());992 }993 994 return cgf.getBuilder().getNullPtr(destCIRTy, loc);995}996 997mlir::Value CIRGenFunction::emitDynamicCast(Address thisAddr,998 const CXXDynamicCastExpr *dce) {999 mlir::Location loc = getLoc(dce->getSourceRange());1000 1001 cgm.emitExplicitCastExprType(dce, this);1002 QualType destTy = dce->getTypeAsWritten();1003 QualType srcTy = dce->getSubExpr()->getType();1004 1005 // C++ [expr.dynamic.cast]p7:1006 // If T is "pointer to cv void," then the result is a pointer to the most1007 // derived object pointed to by v.1008 bool isDynCastToVoid = destTy->isVoidPointerType();1009 bool isRefCast = destTy->isReferenceType();1010 1011 QualType srcRecordTy;1012 QualType destRecordTy;1013 if (isDynCastToVoid) {1014 srcRecordTy = srcTy->getPointeeType();1015 // No destRecordTy.1016 } else if (const PointerType *destPTy = destTy->getAs<PointerType>()) {1017 srcRecordTy = srcTy->castAs<PointerType>()->getPointeeType();1018 destRecordTy = destPTy->getPointeeType();1019 } else {1020 srcRecordTy = srcTy;1021 destRecordTy = destTy->castAs<ReferenceType>()->getPointeeType();1022 }1023 1024 assert(srcRecordTy->isRecordType() && "source type must be a record type!");1025 assert(!cir::MissingFeatures::emitTypeCheck());1026 1027 if (dce->isAlwaysNull())1028 return emitDynamicCastToNull(*this, loc, destTy);1029 1030 auto destCirTy = mlir::cast<cir::PointerType>(convertType(destTy));1031 return cgm.getCXXABI().emitDynamicCast(*this, loc, srcRecordTy, destRecordTy,1032 destCirTy, isRefCast, thisAddr);1033}1034