clang 24.0.0git
CIRGenExprCXX.cpp
Go to the documentation of this file.
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This contains code dealing with code generation of C++ expressions
10//
11//===----------------------------------------------------------------------===//
12
13#include "CIRGenCXXABI.h"
15#include "CIRGenFunction.h"
16
17#include "clang/AST/CharUnits.h"
18#include "clang/AST/DeclCXX.h"
19#include "clang/AST/ExprCXX.h"
20#include "clang/AST/ExprObjC.h"
24#include "llvm/ADT/Sequence.h"
25#include "llvm/Support/TrailingObjects.h"
26
27using namespace clang;
28using namespace clang::CIRGen;
29
30namespace {
31struct MemberCallInfo {
32 RequiredArgs reqArgs;
33 // Number of prefix arguments for the call. Ignores the `this` pointer.
34 unsigned prefixSize;
35};
36} // namespace
37
39 CIRGenFunction &cgf, const CXXMethodDecl *md, mlir::Value thisPtr,
40 mlir::Value implicitParam, QualType implicitParamTy, const CallExpr *ce,
41 CallArgList &args, CallArgList *rtlArgs) {
42 assert(ce == nullptr || isa<CXXMemberCallExpr>(ce) ||
44 assert(md->isInstance() &&
45 "Trying to emit a member or operator call expr on a static method!");
46
47 // Push the this ptr.
48 const CXXRecordDecl *rd =
50 args.add(RValue::get(thisPtr), cgf.getTypes().deriveThisType(rd, md));
51
52 // If there is an implicit parameter (e.g. VTT), emit it.
53 if (implicitParam) {
54 args.add(RValue::get(implicitParam), implicitParamTy);
55 }
56
57 const auto *fpt = md->getType()->castAs<FunctionProtoType>();
58 RequiredArgs required =
60 unsigned prefixSize = args.size() - 1;
61
62 // Add the rest of the call args
63 if (rtlArgs) {
64 // Special case: if the caller emitted the arguments right-to-left already
65 // (prior to emitting the *this argument), we're done. This happens for
66 // assignment operators.
67 args.addFrom(*rtlArgs);
68 } else if (ce) {
69 // Special case: skip first argument of CXXOperatorCall (it is "this").
70 unsigned argsToSkip = isa<CXXOperatorCallExpr>(ce) ? 1 : 0;
71 cgf.emitCallArgs(args, fpt, drop_begin(ce->arguments(), argsToSkip),
72 ce->getDirectCallee());
73 } else {
74 assert(
75 fpt->getNumParams() == 0 &&
76 "No CallExpr specified for function with non-zero number of arguments");
77 }
78
79 // return {required, prefixSize};
80 return {required, prefixSize};
81}
82
86 const BinaryOperator *bo =
88 const Expr *baseExpr = bo->getLHS();
89 const Expr *memFnExpr = bo->getRHS();
90
91 const auto *mpt = memFnExpr->getType()->castAs<MemberPointerType>();
92 const auto *fpt = mpt->getPointeeType()->castAs<FunctionProtoType>();
93
94 // Emit the 'this' pointer.
95 Address thisAddr = Address::invalid();
96 if (bo->getOpcode() == BO_PtrMemI)
97 thisAddr = emitPointerWithAlignment(baseExpr);
98 else
99 thisAddr = emitLValue(baseExpr).getAddress();
100
102
103 // Get the member function pointer.
104 mlir::Value memFnPtr = emitScalarExpr(memFnExpr);
105
106 // Resolve the member function pointer to the actual callee and adjust the
107 // "this" pointer for call.
108 mlir::Location loc = getLoc(ce->getExprLoc());
109 auto [/*mlir::Value*/ calleePtr, /*mlir::Value*/ adjustedThis] =
110 builder.createGetMethod(loc, memFnPtr, thisAddr.getPointer());
111
112 // Prepare the call arguments.
113 CallArgList argsList;
114 argsList.add(RValue::get(adjustedThis), getContext().VoidPtrTy);
115 emitCallArgs(argsList, fpt, ce->arguments());
116
118
119 // Build the call.
120 CIRGenCallee callee(fpt, calleePtr.getDefiningOp());
121 return emitCall(cgm.getTypes().arrangeCXXMethodCall(argsList, fpt, required,
122 /*PrefixSize=*/0),
123 callee, returnValue, argsList, nullptr, ce == mustTailCall,
124 ce->getSourceRange());
125}
126
129 bool hasQualifier, NestedNameSpecifier qualifier, bool isArrow,
130 const Expr *base) {
132
133 // Compute the object pointer.
134 bool canUseVirtualCall = md->isVirtual() && !hasQualifier;
135 const CXXMethodDecl *devirtualizedMethod = nullptr;
136 // TODO: This devirtualization logic should be hoisted to the AST layer so it
137 // can be shared with classic codegen (see CGExprCXX.cpp).
138 if (canUseVirtualCall &&
139 md->getDevirtualizedMethod(base, getLangOpts().AppleKext)) {
140 const CXXRecordDecl *bestDynamicDecl = base->getBestDynamicClassType();
141 devirtualizedMethod = md->getCorrespondingMethodInClass(bestDynamicDecl);
142 assert(devirtualizedMethod);
143 const CXXRecordDecl *devirtualizedClass = devirtualizedMethod->getParent();
144 const Expr *inner = base->IgnoreParenBaseCasts();
145 auto getCXXRecord = [](const Expr *e) -> const CXXRecordDecl * {
146 QualType t = e->getType();
147 if (t->isRecordType())
148 return t->getAsCXXRecordDecl();
149 return t->getPointeeCXXRecordDecl();
150 };
151 if (devirtualizedMethod->getReturnType().getCanonicalType() !=
153 // If the return types are not the same, this might be a case where more
154 // code needs to run to compensate for it. For example, the derived
155 // method might return a type that inherits from the return type of MD
156 // and has a prefix.
157 // For now we just avoid devirtualizing these covariant cases.
158 devirtualizedMethod = nullptr;
159 else if (getCXXRecord(inner) == devirtualizedClass)
160 // If the class of the Inner expression is where the dynamic method
161 // is defined, build the this pointer from it.
162 base = inner;
163 else if (getCXXRecord(base) != devirtualizedClass) {
164 // If the method is defined in a class that is not the best dynamic
165 // one or the one of the full expression, we would have to build
166 // a derived-to-base cast to compute the correct this pointer, but
167 // we don't have support for that yet, so do a virtual call.
168 devirtualizedMethod = nullptr;
169 }
170 }
171
172 // Note on trivial assignment
173 // --------------------------
174 // Classic codegen avoids generating the trivial copy/move assignment operator
175 // when it isn't necessary, choosing instead to just produce IR with an
176 // equivalent effect. We have chosen not to do that in CIR, instead emitting
177 // trivial copy/move assignment operators and allowing later transformations
178 // to optimize them away if appropriate.
179
180 // C++17 demands that we evaluate the RHS of a (possibly-compound) assignment
181 // operator before the LHS.
182 CallArgList rtlArgStorage;
183 CallArgList *rtlArgs = nullptr;
184 if (auto *oce = dyn_cast<CXXOperatorCallExpr>(ce)) {
185 if (oce->isAssignmentOp()) {
186 rtlArgs = &rtlArgStorage;
187 emitCallArgs(*rtlArgs, md->getType()->castAs<FunctionProtoType>(),
188 drop_begin(ce->arguments(), 1), ce->getDirectCallee(),
189 /*ParamsToSkip*/ 0, EvaluationOrder::ForceRightToLeft);
190 }
191 }
192
193 LValue thisPtr;
194 if (isArrow) {
195 LValueBaseInfo baseInfo;
197 Address thisValue = emitPointerWithAlignment(base, &baseInfo);
198 thisPtr = makeAddrLValue(thisValue, base->getType(), baseInfo);
199 } else {
200 thisPtr = emitLValue(base);
201 }
202
203 if (isa<CXXConstructorDecl>(md)) {
204 cgm.errorNYI(ce->getSourceRange(),
205 "emitCXXMemberOrOperatorMemberCallExpr: constructor call");
206 return RValue::get(nullptr);
207 }
208
209 if ((md->isTrivial() || (md->isDefaulted() && md->getParent()->isUnion())) &&
211 return RValue::get(nullptr);
212
213 // Compute the function type we're calling
214 const CXXMethodDecl *calleeDecl =
215 devirtualizedMethod ? devirtualizedMethod : md;
216 const CIRGenFunctionInfo *fInfo = nullptr;
217 if (const auto *dtor = dyn_cast<CXXDestructorDecl>(calleeDecl))
218 fInfo = &cgm.getTypes().arrangeCXXStructorDeclaration(
220 else
221 fInfo = &cgm.getTypes().arrangeCXXMethodDeclaration(calleeDecl);
222
223 cir::FuncType ty = cgm.getTypes().getFunctionType(*fInfo);
224
227
228 // C++ [class.virtual]p12:
229 // Explicit qualification with the scope operator (5.1) suppresses the
230 // virtual call mechanism.
231 //
232 // We also don't emit a virtual call if the base expression has a record type
233 // because then we know what the type is.
234 bool useVirtualCall = canUseVirtualCall && !devirtualizedMethod;
235
236 if (const auto *dtor = dyn_cast<CXXDestructorDecl>(calleeDecl)) {
237 assert(ce->arg_begin() == ce->arg_end() &&
238 "Destructor shouldn't have explicit parameters");
239 assert(returnValue.isNull() && "Destructor shouldn't have return value");
240 if (useVirtualCall) {
241 cgm.getCXXABI().emitVirtualDestructorCall(*this, dtor, Dtor_Complete,
242 thisPtr.getAddress(),
244 } else {
245 GlobalDecl globalDecl(dtor, Dtor_Complete);
246 CIRGenCallee callee;
248 if (!devirtualizedMethod) {
250 cgm.getAddrOfCXXStructor(globalDecl, fInfo, ty), globalDecl);
251 } else {
252 callee = CIRGenCallee::forDirect(cgm.getAddrOfFunction(globalDecl, ty),
253 globalDecl);
254 }
255
256 QualType thisTy =
257 isArrow ? base->getType()->getPointeeType() : base->getType();
258 // CIRGen does not pass CallOrInvoke here (different from OG LLVM codegen)
259 // because in practice it always null even in OG.
260 emitCXXDestructorCall(globalDecl, callee, thisPtr.getPointer(), thisTy,
261 /*implicitParam=*/nullptr,
262 /*implicitParamTy=*/QualType(), ce);
263 }
264 return RValue::get(nullptr);
265 }
266
267 CIRGenCallee callee;
268 if (useVirtualCall) {
269 callee = CIRGenCallee::forVirtual(ce, md, thisPtr.getAddress(), ty);
270 } else {
272 if (getLangOpts().AppleKext) {
273 cgm.errorNYI(ce->getSourceRange(),
274 "emitCXXMemberOrOperatorMemberCallExpr: AppleKext");
275 return RValue::get(nullptr);
276 }
277
278 callee = CIRGenCallee::forDirect(cgm.getAddrOfFunction(calleeDecl, ty),
279 GlobalDecl(calleeDecl));
280 }
281
282 if (md->isVirtual()) {
283 Address newThisAddr =
284 cgm.getCXXABI().adjustThisArgumentForVirtualFunctionCall(
285 *this, calleeDecl, thisPtr.getAddress(), useVirtualCall);
286 thisPtr.setAddress(newThisAddr);
287 }
288
290 calleeDecl, callee, returnValue, thisPtr.getPointer(),
291 /*ImplicitParam=*/nullptr, QualType(), ce, rtlArgs);
292}
293
294RValue
296 const CXXMethodDecl *md,
298 assert(md->isInstance() &&
299 "Trying to emit a member call expr on a static method!");
301 e, md, returnValue, /*HasQualifier=*/false, /*Qualifier=*/std::nullopt,
302 /*IsArrow=*/false, e->getArg(0));
303}
304
307 // Emit as a device kernel call if CUDA device code is to be generated.
308 if (!getLangOpts().HIP && getLangOpts().CUDAIsDevice)
309 cgm.errorNYI("CUDA Device side kernel call");
310 return cgm.getCUDARuntime().emitCUDAKernelCallExpr(*this, expr, returnValue);
311}
312
314 const CXXMethodDecl *md, const CIRGenCallee &callee,
315 ReturnValueSlot returnValue, mlir::Value thisPtr, mlir::Value implicitParam,
316 QualType implicitParamTy, const CallExpr *ce, CallArgList *rtlArgs) {
317 const auto *fpt = md->getType()->castAs<FunctionProtoType>();
318 CallArgList args;
319 MemberCallInfo callInfo = commonBuildCXXMemberOrOperatorCall(
320 *this, md, thisPtr, implicitParam, implicitParamTy, ce, args, rtlArgs);
321 auto &fnInfo = cgm.getTypes().arrangeCXXMethodCall(
322 args, fpt, callInfo.reqArgs, callInfo.prefixSize);
323 assert((ce || currSrcLoc) && "expected source location");
324 SourceRange loc = ce ? ce->getSourceRange() : *currSrcLoc;
325 return emitCall(fnInfo, callee, returnValue, args, nullptr,
326 ce && ce == mustTailCall, loc);
327}
328
330 Address destPtr,
331 const CXXRecordDecl *base) {
332 if (base->isEmpty())
333 return;
334
335 const ASTRecordLayout &layout = cgf.getContext().getASTRecordLayout(base);
336 CharUnits nvSize = layout.getNonVirtualSize();
337
338 // We cannot simply zero-initialize the entire base sub-object if vbptrs are
339 // present, they are initialized by the most derived class before calling the
340 // constructor.
342 stores.emplace_back(CharUnits::Zero(), nvSize);
343
344 // Each store is split by the existence of a vbptr.
345 // TODO(cir): This only needs handling for the MS CXXABI.
347
348 // If the type contains a pointer to data member we can't memset it to zero.
349 // Instead, create a null constant and copy it to the destination.
350 // TODO: there are other patterns besides zero that we can usefully memset,
351 // like -1, which happens to be the pattern used by member-pointers.
352 // TODO: isZeroInitializable can be over-conservative in the case where a
353 // virtual base contains a member pointer.
354 mlir::TypedAttr nullConstantForBase = cgf.cgm.emitNullConstantForBase(base);
355 if (!cgf.getBuilder().isNullValue(nullConstantForBase)) {
356 cgf.cgm.errorNYI(
357 base->getSourceRange(),
358 "emitNullBaseClassInitialization: base constant is not null");
359 } else {
360 // Otherwise, just memset the whole thing to zero. This is legal
361 // because in LLVM, all default initializers (other than the ones we just
362 // handled above) are guaranteed to have a bit pattern of all zeros.
363 // TODO(cir): When the MS CXXABI is supported, we will need to iterate over
364 // `stores` and create a separate memset for each one. For now, we know that
365 // there will only be one store and it will begin at offset zero, so that
366 // simplifies this code considerably.
367 assert(stores.size() == 1 && "Expected only one store");
368 assert(stores[0].first == CharUnits::Zero() &&
369 "Expected store to begin at offset zero");
370 CIRGenBuilderTy &builder = cgf.getBuilder();
371 mlir::Location loc = cgf.getLoc(base->getBeginLoc());
372 builder.createStore(loc, builder.getConstant(loc, nullConstantForBase),
373 destPtr);
374 }
375}
376
378 AggValueSlot dest) {
379 assert(!dest.isIgnored() && "Must have a destination!");
380 const CXXConstructorDecl *cd = e->getConstructor();
381
382 // If we require zero initialization before (or instead of) calling the
383 // constructor, as can be the case with a non-user-provided default
384 // constructor, emit the zero initialization now, unless destination is
385 // already zeroed.
386 if (e->requiresZeroInitialization() && !dest.isZeroed()) {
387 switch (e->getConstructionKind()) {
391 e->getType());
392 break;
396 cd->getParent());
397 break;
398 }
399 }
400
401 // If this is a call to a trivial default constructor, do nothing.
402 if (cd->isTrivial() && cd->isDefaultConstructor())
403 return;
404
405 // Elide the constructor if we're constructing from a temporary
406 if (getLangOpts().ElideConstructors && e->isElidable()) {
407 // FIXME: This only handles the simplest case, where the source object is
408 // passed directly as the first argument to the constructor. This
409 // should also handle stepping through implicit casts and conversion
410 // sequences which involve two steps, with a conversion operator
411 // follwed by a converting constructor.
412 const Expr *srcObj = e->getArg(0);
413 assert(srcObj->isTemporaryObject(getContext(), cd->getParent()));
414 assert(
415 getContext().hasSameUnqualifiedType(e->getType(), srcObj->getType()));
416 emitAggExpr(srcObj, dest);
417 return;
418 }
419
420 if (const ArrayType *arrayType = getContext().getAsArrayType(e->getType())) {
422 emitCXXAggrConstructorCall(cd, arrayType, dest.getAddress(), e, false);
423 } else {
424
426 bool forVirtualBase = false;
427 bool delegating = false;
428
429 switch (e->getConstructionKind()) {
432 break;
434 // We should be emitting a constructor; GlobalDecl will assert this
435 type = curGD.getCtorType();
436 delegating = true;
437 break;
439 forVirtualBase = true;
440 [[fallthrough]];
442 type = Ctor_Base;
443 break;
444 }
445
446 emitCXXConstructorCall(cd, type, forVirtualBase, delegating, dest, e);
447 }
448}
449
451 const CXXNewExpr *e) {
452 if (!e->isArray())
453 return CharUnits::Zero();
454
455 // No cookie is required if the operator new[] being used is the
456 // reserved placement operator new[].
458 return CharUnits::Zero();
459
460 return cgf.cgm.getCXXABI().getArrayCookieSize(e);
461}
462
463static mlir::Value emitCXXNewAllocSize(CIRGenFunction &cgf, const CXXNewExpr *e,
464 unsigned minElements,
465 mlir::Value &numElements,
466 mlir::Value &sizeWithoutCookie) {
468 mlir::Location loc = cgf.getLoc(e->getSourceRange());
469
470 if (!e->isArray()) {
472 sizeWithoutCookie = cgf.getBuilder().getConstant(
473 loc, cir::IntAttr::get(cgf.sizeTy, typeSize.getQuantity()));
474 return sizeWithoutCookie;
475 }
476
477 // The width of size_t.
478 unsigned sizeWidth = cgf.cgm.getDataLayout().getTypeSizeInBits(cgf.sizeTy);
479
480 // The number of elements can be have an arbitrary integer type;
481 // essentially, we need to multiply it by a constant factor, add a
482 // cookie size, and verify that the result is representable as a
483 // size_t. That's just a gloss, though, and it's wrong in one
484 // important way: if the count is negative, it's an error even if
485 // the cookie size would bring the total size >= 0.
486 //
487 // If the array size is constant, Sema will have prevented negative
488 // values.
489
490 // Compute the constant factor.
491 llvm::APInt arraySizeMultiplier(sizeWidth, 1);
492 while (const ConstantArrayType *cat =
494 type = cat->getElementType();
495 arraySizeMultiplier *= cat->getSize();
496 }
497
499 llvm::APInt typeSizeMultiplier(sizeWidth, typeSize.getQuantity());
500 typeSizeMultiplier *= arraySizeMultiplier;
501
502 // Figure out the cookie size.
503 llvm::APInt cookieSize(sizeWidth,
504 calculateCookiePadding(cgf, e).getQuantity());
505
506 // This will be a size_t.
507 mlir::Value size;
508
509 // Emit the array size expression.
510 // We multiply the size of all dimensions for NumElements.
511 // e.g for 'int[2][3]', ElemType is 'int' and NumElements is 6.
512 const Expr *arraySize = *e->getArraySize();
513 mlir::Attribute constNumElements =
514 ConstantEmitter(cgf.cgm, &cgf)
515 .tryEmitAbstract(arraySize, arraySize->getType());
516 if (constNumElements) {
517 // Get an APInt from the constant
518 auto numEltsAttr = mlir::cast<cir::IntAttr>(constNumElements);
519 const llvm::APInt &count = numEltsAttr.getValue();
520
521 [[maybe_unused]] unsigned numElementsWidth = count.getBitWidth();
522 bool hasAnyOverflow = false;
523
524 // The equivalent code in CodeGen/CGExprCXX.cpp handles these cases as
525 // overflow, but that should never happen. The size argument is implicitly
526 // cast to a size_t, so it can never be negative and numElementsWidth will
527 // always equal sizeWidth. However, sometimes in operator-new, it seems that
528 // `numElements` might remain an 'int', so we have to support smaller than
529 // that. We immediately do the zextOrTrunc below (which should really only
530 // do zext, since our assert handles the trunc), but it will make sure the
531 // width is correct.
532 assert(!(numEltsAttr.isSigned() && count.isNegative()) &&
533 "Expected non-negative array size");
534 assert(numElementsWidth <= sizeWidth &&
535 "Expected a size_t array size constant");
536
537 // Okay, compute a count at the right width.
538 llvm::APInt adjustedCount = count.zextOrTrunc(sizeWidth);
539
540 // Scale numElements by that. This might overflow, but we don't
541 // care because it only overflows if allocationSize does too, and
542 // if that overflows then we shouldn't use this.
543 // This emits a constant that may not be used, but we can't tell here
544 // whether it will be needed or not.
545 numElements =
546 cgf.getBuilder().getConstInt(loc, adjustedCount * arraySizeMultiplier);
547
548 // Compute the size before cookie, and track whether it overflowed.
549 bool overflow;
550 llvm::APInt allocationSize =
551 adjustedCount.umul_ov(typeSizeMultiplier, overflow);
552 hasAnyOverflow |= overflow;
553
554 // Add in the cookie, and check whether it's overflowed.
555 if (cookieSize != 0) {
556 // Save the current size without a cookie. This shouldn't be
557 // used if there was overflow
558 sizeWithoutCookie = cgf.getBuilder().getConstInt(
559 loc, allocationSize.zextOrTrunc(sizeWidth));
560
561 allocationSize = allocationSize.uadd_ov(cookieSize, overflow);
562 hasAnyOverflow |= overflow;
563 }
564
565 // On overflow, produce a -1 so operator new will fail
566 if (hasAnyOverflow) {
567 size =
568 cgf.getBuilder().getConstInt(loc, llvm::APInt::getAllOnes(sizeWidth));
569 } else {
570 size = cgf.getBuilder().getConstInt(loc, allocationSize);
571 }
572 } else {
573 // Create a value for the variable number of elements
574 numElements = cgf.emitScalarExpr(*e->getArraySize());
575 auto numElementsType = mlir::cast<cir::IntType>(numElements.getType());
576 unsigned numElementsWidth = numElementsType.getWidth();
577
578 // The number of elements can have an arbitrary integer type;
579 // essentially, we need to multiply it by a constant factor, add a
580 // cookie size, and verify that the result is representable as a
581 // size_t. That's just a gloss, though, and it's wrong in one
582 // important way: if the count is negative, it's an error even if
583 // the cookie size would bring the total size >= 0.
584 bool isSigned =
585 (*e->getArraySize())->getType()->isSignedIntegerOrEnumerationType();
586
587 // There are up to five conditions we need to test for:
588 // 1) if isSigned, we need to check whether numElements is negative;
589 // 2) if numElementsWidth > sizeWidth, we need to check whether
590 // numElements is larger than something representable in size_t;
591 // 3) if minElements > 0, we need to check whether numElements is smaller
592 // than that.
593 // 4) we need to compute
594 // sizeWithoutCookie := numElements * typeSizeMultiplier
595 // and check whether it overflows; and
596 // 5) if we need a cookie, we need to compute
597 // size := sizeWithoutCookie + cookieSize
598 // and check whether it overflows.
599
600 mlir::Value hasOverflow;
601
602 // If numElementsWidth > sizeWidth, then one way or another, we're
603 // going to have to do a comparison for (2), and this happens to
604 // take care of (1), too.
605 if (numElementsWidth > sizeWidth) {
606 llvm::APInt threshold =
607 llvm::APInt::getOneBitSet(numElementsWidth, sizeWidth);
608
609 // Use an unsigned comparison regardless of the sign of numElements.
610 mlir::Value unsignedNumElements = numElements;
611 if (isSigned)
612 unsignedNumElements = cgf.getBuilder().createIntCast(
613 numElements, cgf.getBuilder().getUIntNTy(numElementsWidth));
614
615 mlir::Value thresholdV =
616 cgf.getBuilder().getConstInt(loc, threshold, /*isUnsigned=*/true);
617 hasOverflow = cgf.getBuilder().createCompare(
618 loc, cir::CmpOpKind::ge, unsignedNumElements, thresholdV);
619 numElements = cgf.getBuilder().createIntCast(
620 unsignedNumElements, mlir::cast<cir::IntType>(cgf.sizeTy));
621
622 // Otherwise, if we're signed, we want to sext up to size_t.
623 } else if (isSigned) {
624 if (numElementsWidth < sizeWidth)
625 numElements = cgf.getBuilder().createIntCast(
626 numElements, cgf.getBuilder().getSIntNTy(sizeWidth));
627
628 // If there's a non-1 type size multiplier, then we can do the
629 // signedness check at the same time as we do the multiply
630 // because a negative number times anything will cause an
631 // unsigned overflow. Otherwise, we have to do it here. But at
632 // least in this case, we can subsume the >= minElements check.
633 if (typeSizeMultiplier == 1)
634 hasOverflow = cgf.getBuilder().createCompare(
635 loc, cir::CmpOpKind::lt, numElements,
636 cgf.getBuilder().getConstInt(loc, numElements.getType(),
637 minElements));
638
639 numElements = cgf.getBuilder().createIntCast(
640 numElements, mlir::cast<cir::IntType>(cgf.sizeTy));
641
642 // Otherwise, zext up to size_t if necessary.
643 } else if (numElementsWidth < sizeWidth) {
644 numElements = cgf.getBuilder().createIntCast(
645 numElements, mlir::cast<cir::IntType>(cgf.sizeTy));
646 }
647
648 assert(numElements.getType() == cgf.sizeTy);
649
650 if (minElements) {
651 // Don't allow allocation of fewer elements than we have initializers.
652 if (!hasOverflow) {
653 mlir::Value minElementsV = cgf.getBuilder().getConstInt(
654 loc, llvm::APInt(sizeWidth, minElements));
655 hasOverflow = cgf.getBuilder().createCompare(loc, cir::CmpOpKind::lt,
656 numElements, minElementsV);
657 } else if (numElementsWidth > sizeWidth) {
658 // The other existing overflow subsumes this check.
659 // We do an unsigned comparison, since any signed value < -1 is
660 // taken care of either above or below.
661 mlir::Value minElementsV = cgf.getBuilder().getConstInt(
662 loc, llvm::APInt(sizeWidth, minElements));
663 hasOverflow = cgf.getBuilder().createOr(
664 loc, hasOverflow,
665 cgf.getBuilder().createCompare(loc, cir::CmpOpKind::lt, numElements,
666 minElementsV));
667 }
668 }
669
670 size = numElements;
671
672 // Multiply by the type size if necessary. This multiplier
673 // includes all the factors for nested arrays.
674 //
675 // This step also causes numElements to be scaled up by the
676 // nested-array factor if necessary. Overflow on this computation
677 // can be ignored because the result shouldn't be used if
678 // allocation fails.
679 if (typeSizeMultiplier != 1) {
680 mlir::Value tsmV = cgf.getBuilder().getConstInt(loc, typeSizeMultiplier);
681 auto mulOp = cir::MulOverflowOp::create(
682 cgf.getBuilder(), loc, mlir::cast<cir::IntType>(cgf.sizeTy), size,
683 tsmV);
684
685 if (hasOverflow)
686 hasOverflow =
687 cgf.getBuilder().createOr(loc, hasOverflow, mulOp.getOverflow());
688 else
689 hasOverflow = mulOp.getOverflow();
690
691 size = mulOp.getResult();
692
693 // Also scale up numElements by the array size multiplier.
694 if (arraySizeMultiplier != 1) {
695 // If the base element type size is 1, then we can re-use the
696 // multiply we just did.
697 if (typeSize.isOne()) {
698 assert(arraySizeMultiplier == typeSizeMultiplier);
699 numElements = size;
700
701 // Otherwise we need a separate multiply.
702 } else {
703 mlir::Value asmV =
704 cgf.getBuilder().getConstInt(loc, arraySizeMultiplier);
705 numElements = cgf.getBuilder().createMul(loc, numElements, asmV);
706 }
707 }
708 } else {
709 // numElements doesn't need to be scaled.
710 assert(arraySizeMultiplier == 1);
711 }
712
713 // Add in the cookie size if necessary.
714 if (cookieSize != 0) {
715 sizeWithoutCookie = size;
716 mlir::Value cookieSizeV = cgf.getBuilder().getConstInt(loc, cookieSize);
717 auto addOp = cir::AddOverflowOp::create(
718 cgf.getBuilder(), loc, mlir::cast<cir::IntType>(cgf.sizeTy), size,
719 cookieSizeV);
720
721 if (hasOverflow)
722 hasOverflow =
723 cgf.getBuilder().createOr(loc, hasOverflow, addOp.getOverflow());
724 else
725 hasOverflow = addOp.getOverflow();
726
727 size = addOp.getResult();
728 }
729
730 // If we had any possibility of dynamic overflow, make a select to
731 // overwrite 'size' with an all-ones value, which should cause
732 // operator new to throw.
733 if (hasOverflow) {
734 mlir::Value allOnes =
735 cgf.getBuilder().getConstInt(loc, llvm::APInt::getAllOnes(sizeWidth));
736 size = cgf.getBuilder().createSelect(loc, hasOverflow, allOnes, size);
737 }
738 }
739
740 if (cookieSize == 0)
741 sizeWithoutCookie = size;
742 else
743 assert(sizeWithoutCookie && "didn't set sizeWithoutCookie?");
744
745 return size;
746}
747
748/// Emit a call to an operator new or operator delete function, as implicitly
749/// created by new-expressions and delete-expressions.
751 const FunctionDecl *calleeDecl,
752 const FunctionProtoType *calleeType,
753 const CallArgList &args) {
754 cir::CIRCallOpInterface callOrTryCall;
755 cir::FuncOp calleePtr = cgf.cgm.getAddrOfFunction(calleeDecl);
756 CIRGenCallee callee =
757 CIRGenCallee::forDirect(calleePtr, GlobalDecl(calleeDecl));
758 RValue rv = cgf.emitCall(
759 cgf.cgm.getTypes().arrangeFreeFunctionCall(args, calleeType), callee,
760 ReturnValueSlot(), args, /*isMustTail=*/false, &callOrTryCall);
761
762 /// C++1y [expr.new]p10:
763 /// [In a new-expression,] an implementation is allowed to omit a call
764 /// to a replaceable global allocation function.
765 ///
766 /// We model such elidable calls with the 'builtin' attribute.
767 if (calleeDecl->isReplaceableGlobalAllocationFunction() && calleePtr) {
768 if (calleePtr->hasAttr(cir::CIRDialect::getNoBuiltinAttrName()))
769 callOrTryCall->setAttr(cir::CIRDialect::getBuiltinAttrName(),
770 mlir::UnitAttr::get(callOrTryCall->getContext()));
771
772 // A sane operator new does not read or write accessible memory.
773 if (cgf.cgm.getCodeGenOpts().AssumeSaneOperatorNew &&
774 calleeDecl->getDeclName().isAnyOperatorNew()) {
775 // FIXME: inaccessiblemem could cause issues if LTO makes the
776 // previously inaccessible memory accessible after linking.
777 callOrTryCall.setMemoryEffectsAttr(
778 cir::MemoryEffectsAttr::inaccessibleOrErrnoMemOnly(
779 callOrTryCall->getContext(), cir::ModRefInfo::ModRef,
780 cir::ModRefInfo::Mod));
781 }
782 }
783
784 return rv;
785}
786
788 const CallExpr *callExpr,
790 CallArgList args;
791 emitCallArgs(args, type, callExpr->arguments());
792 // Find the allocation or deallocation function that we're calling.
793 ASTContext &astContext = getContext();
794 assert(op == OO_New || op == OO_Delete);
796
797 clang::DeclContextLookupResult lookupResult =
798 astContext.getTranslationUnitDecl()->lookup(name);
799 for (const NamedDecl *decl : lookupResult) {
800 if (const auto *funcDecl = dyn_cast<FunctionDecl>(decl)) {
801 if (astContext.hasSameType(funcDecl->getType().getTypePtr(), type)) {
802 if (sanOpts.has(SanitizerKind::AllocToken)) {
803 // TODO: Set !alloc_token metadata.
805 cgm.errorNYI("Alloc token sanitizer not yet supported!");
806 }
807
808 // Emit the call to operator new/delete.
809 return emitNewDeleteCall(*this, funcDecl, type, args);
810 }
811 }
812 }
813
814 llvm_unreachable("predeclared global operator new/delete is missing");
815}
816
817namespace {
818template <typename Traits> struct PlacementArg {
819 typename Traits::RValueTy argValue;
820 QualType argType;
821};
822
823/// A cleanup to call the given 'operator delete' function upon abnormal
824/// exit from a new expression. Templated on a traits type that deals with
825/// ensuring that the arguments dominate the cleanup if necessary.
826template <typename Traits>
827class CallDeleteDuringNew final
828 : public EHScopeStack::Cleanup,
829 private llvm::TrailingObjects<CallDeleteDuringNew<Traits>,
830 PlacementArg<Traits>> {
831 using TrailingObj =
832 llvm::TrailingObjects<CallDeleteDuringNew<Traits>, PlacementArg<Traits>>;
833 friend TrailingObj;
834 using TrailingObj::getTrailingObjects;
835
836 /// Type used to hold llvm::Value*s.
837 typedef typename Traits::ValueTy ValueTy;
838 /// Type used to hold RValues.
839 typedef typename Traits::RValueTy RValueTy;
840
841 unsigned numPlacementArgs : 30;
842 LLVM_PREFERRED_TYPE(AlignedAllocationMode)
843 unsigned passAlignmentToPlacementDelete : 1;
844 const FunctionDecl *operatorDelete;
845 ValueTy ptr;
846 ValueTy allocSize;
847 CharUnits allocAlign;
848
849 PlacementArg<Traits> *getPlacementArgs() { return getTrailingObjects(); }
850
851public:
852 void setPlacementArg(unsigned i, RValueTy argValue, QualType argType) {
853 assert(i < numPlacementArgs && "index out of range");
854 getPlacementArgs()[i] = {argValue, argType};
855 }
856
857 static size_t getExtraSize(size_t numPlacementArgs) {
858 return TrailingObj::template additionalSizeToAlloc<PlacementArg<Traits>>(
859 numPlacementArgs);
860 }
861
862 CallDeleteDuringNew(size_t numPlacementArgs,
863 const FunctionDecl *operatorDelete, ValueTy ptr,
864 ValueTy allocSize,
865 const ImplicitAllocationParameters &iap,
866 CharUnits allocAlign)
867 : numPlacementArgs(numPlacementArgs),
868 passAlignmentToPlacementDelete(isAlignedAllocation(iap.PassAlignment)),
869 operatorDelete(operatorDelete), ptr(ptr), allocSize(allocSize),
870 allocAlign(allocAlign) {}
871
872 void emit(CIRGenFunction &cgf, Flags flags) override {
873 const auto *fpt = operatorDelete->getType()->castAs<FunctionProtoType>();
874 CallArgList deleteArgs;
875
876 unsigned firstNonTypeArg = 0;
877 TypeAwareAllocationMode typeAwareDeallocation = TypeAwareAllocationMode::No;
879
880 // The first argument after type-identity parameter (if any) is always
881 // a void* (or C* for a destroying operator delete for class type C).
882 deleteArgs.add(Traits::get(cgf, ptr), fpt->getParamType(firstNonTypeArg));
883
884 // Figure out what other parameters we should be implicitly passing.
885 UsualDeleteParams params;
886 if (numPlacementArgs) {
887 // A placement deallocation function is implicitly passed an alignment
888 // if the placement allocation function was, but is never passed a size.
889 params.Alignment =
890 alignedAllocationModeFromBool(passAlignmentToPlacementDelete);
891 params.TypeAwareDelete = typeAwareDeallocation;
893 } else {
894 // For a non-placement new-expression, 'operator delete' can take a
895 // size and/or an alignment if it has the right parameters.
896 params = operatorDelete->getUsualDeleteParams();
897 }
898
899 assert(!params.DestroyingDelete &&
900 "should not call destroying delete in a new-expression");
901
902 // The second argument can be a std::size_t (for non-placement delete).
903 if (params.Size)
904 deleteArgs.add(Traits::get(cgf, allocSize),
905 cgf.getContext().getSizeType());
906
907 // The next (second or third) argument can be a std::align_val_t, which
908 // is an enum whose underlying type is std::size_t.
909 // FIXME: Use the right type as the parameter type. Note that in a call
910 // to operator delete(size_t, ...), we may not have it available.
911 if (isAlignedAllocation(params.Alignment)) {
912 QualType sizeType = cgf.getContext().getSizeType();
913 cir::ConstantOp align = cgf.getBuilder().getAlignment(
914 cgf.getLoc(*cgf.currSrcLoc), cgf.convertType(sizeType), allocAlign);
915 deleteArgs.add(RValue::get(align), sizeType);
916 }
917
918 // Pass the rest of the arguments, which must match exactly.
919 for (unsigned i = 0; i != numPlacementArgs; ++i) {
920 auto arg = getPlacementArgs()[i];
921 deleteArgs.add(Traits::get(cgf, arg.argValue), arg.argType);
922 }
923
924 // Call 'operator delete'.
925 emitNewDeleteCall(cgf, operatorDelete, fpt, deleteArgs);
926 }
927};
928} // namespace
929
930/// Enter a cleanup to call 'operator delete' if the initializer in a
931/// new-expression throws.
933 Address newPtr, mlir::Value allocSize,
934 CharUnits allocAlign,
935 const CallArgList &newArgs) {
936 unsigned numNonPlacementArgs = e->getNumImplicitArgs();
937
938 // If we're not inside a conditional branch, then the cleanup will
939 // dominate and we can do the easier (and more efficient) thing.
940 if (!cgf.isInConditionalBranch()) {
941 struct DirectCleanupTraits {
942 typedef mlir::Value ValueTy;
943 typedef RValue RValueTy;
944 static RValue get(CIRGenFunction &, ValueTy v) { return RValue::get(v); }
945 static RValue get(CIRGenFunction &, RValueTy v) { return v; }
946 };
947
948 typedef CallDeleteDuringNew<DirectCleanupTraits> DirectCleanup;
949
951 DirectCleanup *cleanup = cgf.ehStack.pushCleanupWithExtra<DirectCleanup>(
953 newPtr.getPointer(), allocSize, e->implicitAllocationParameters(),
954 allocAlign);
955 for (auto i : llvm::seq<unsigned>(0, e->getNumPlacementArgs())) {
956 const CallArg &arg = newArgs[i + numNonPlacementArgs];
957 cleanup->setPlacementArg(
958 i, arg.getRValue(cgf, cgf.getLoc(e->getSourceRange())), arg.ty);
959 }
960
961 return;
962 }
963
964 // Otherwise, we need to save all this stuff.
965 auto saveValue = [&](mlir::Value value) -> mlir::Value {
967 cgf.cgm.getDataLayout().getABITypeAlign(value.getType()));
968 Address alloca = cgf.createTempAlloca(value.getType(), align,
969 value.getLoc(), "cond-cleanup.save");
970 cgf.getBuilder().createStore(value.getLoc(), value, alloca);
971 return alloca.emitRawPointer();
972 };
973
974 mlir::Value savedNewPtr = saveValue(newPtr.getPointer());
975 mlir::Value savedAllocSize = saveValue(allocSize);
976
977 struct ConditionalCleanupTraits {
978 typedef mlir::Value ValueTy;
979 typedef mlir::Value RValueTy;
980 static RValue get(CIRGenFunction &cgf, ValueTy v) {
981 while (cir::CastOp castOp = v.getDefiningOp<cir::CastOp>()) {
982 if (castOp.getKind() != cir::CastKind::address_space &&
983 castOp.getKind() != cir::CastKind::bitcast)
984 break;
985 v = castOp.getSrc();
986 }
987 cir::AllocaOp alloca = v.getDefiningOp<cir::AllocaOp>();
989 alloca.getLoc(), alloca.getAllocaType(), alloca,
990 llvm::MaybeAlign(alloca.getAlignment())));
991 }
992 };
993 typedef CallDeleteDuringNew<ConditionalCleanupTraits> ConditionalCleanup;
994
996 ConditionalCleanup *cleanup =
997 cgf.ehStack.pushCleanupWithExtra<ConditionalCleanup>(
999 savedNewPtr, savedAllocSize, e->implicitAllocationParameters(),
1000 allocAlign);
1001 for (auto i : llvm::seq<unsigned>(0, e->getNumPlacementArgs())) {
1002 const CallArg &arg = newArgs[i + numNonPlacementArgs];
1003 cleanup->setPlacementArg(
1004 i,
1005 saveValue(
1006 arg.getRValue(cgf, cgf.getLoc(e->getSourceRange())).getValue()),
1007 arg.ty);
1008 }
1009
1010 cgf.initFullExprCleanup();
1011}
1012
1013static void storeAnyExprIntoOneUnit(CIRGenFunction &cgf, const Expr *init,
1014 QualType allocType, Address newPtr,
1015 AggValueSlot::Overlap_t mayOverlap) {
1016 // FIXME: Refactor with emitExprAsInit.
1017 switch (cgf.getEvaluationKind(allocType)) {
1018 case cir::TEK_Scalar:
1019 cgf.emitScalarInit(init, cgf.makeAddrLValue(newPtr, allocType), false);
1020 return;
1021 case cir::TEK_Complex:
1022 cgf.emitComplexExprIntoLValue(init, cgf.makeAddrLValue(newPtr, allocType),
1023 /*isInit*/ true);
1024 return;
1025 case cir::TEK_Aggregate: {
1029 newPtr, allocType.getQualifiers(), AggValueSlot::IsDestructed,
1031 cgf.emitAggExpr(init, slot);
1032 return;
1033 }
1034 }
1035 llvm_unreachable("bad evaluation kind");
1036}
1037
1039 const CXXNewExpr *e, QualType elementType, mlir::Type elementTy,
1040 Address beginPtr, mlir::Value numElements,
1041 mlir::Value allocSizeWithoutCookie) {
1042 // If we have a type with trivial initialization and no initializer,
1043 // there's nothing to do.
1044 if (!e->hasInitializer())
1045 return;
1046
1047 Address curPtr = beginPtr;
1048
1049 unsigned initListElements = 0;
1050
1051 const Expr *init = e->getInitializer();
1052 Address endOfInit = Address::invalid();
1053 QualType::DestructionKind dtorKind = elementType.isDestructedType();
1054 CleanupDeactivationScope deactivation(*this);
1055
1056 // Attempt to perform zero-initialization using memset.
1057 auto tryMemsetInitialization = [&]() -> bool {
1058 mlir::Location loc = numElements.getLoc();
1059
1060 // FIXME: If the type is a pointer-to-data-member under the Itanium ABI,
1061 // we can initialize with a memset to -1.
1062 if (!cgm.getTypes().isZeroInitializable(elementType))
1063 return false;
1064
1065 // Optimization: since zero initialization will just set the memory
1066 // to all zeroes, generate a single memset to do it in one shot.
1067
1068 // Subtract out the size of any elements we've already initialized.
1069 auto remainingSize = allocSizeWithoutCookie;
1070 if (initListElements) {
1071 // We know this can't overflow; we check this when doing the allocation.
1072 unsigned initializedSize =
1073 getContext().getTypeSizeInChars(elementType).getQuantity() *
1074 initListElements;
1075 cir::ConstantOp initSizeOp =
1076 builder.getConstInt(loc, remainingSize.getType(), initializedSize);
1077 remainingSize = builder.createSub(loc, remainingSize, initSizeOp);
1078 }
1079
1080 // Create the memset. Use the Address overload so the destination
1081 // alignment from curPtr is carried onto the memset.
1082 Address voidPtr = curPtr.withElementType(builder, cgm.voidTy);
1083 builder.createMemSet(loc, voidPtr, builder.getConstInt(loc, cgm.uInt8Ty, 0),
1084 remainingSize);
1085 return true;
1086 };
1087
1088 const InitListExpr *ile = dyn_cast<InitListExpr>(init);
1089 const CXXParenListInitExpr *cplie = nullptr;
1090 const StringLiteral *sl = nullptr;
1091 const ObjCEncodeExpr *ocee = nullptr;
1092 const Expr *ignoreParen = nullptr;
1093 if (!ile) {
1094 ignoreParen = init->IgnoreParenImpCasts();
1095 cplie = dyn_cast<CXXParenListInitExpr>(ignoreParen);
1096 sl = dyn_cast<StringLiteral>(ignoreParen);
1097 ocee = dyn_cast<ObjCEncodeExpr>(ignoreParen);
1098 }
1099 // If the initializer is an initializer list, first do the explicit elements.
1100 if (ile || cplie || sl || ocee) {
1101 // Initializing from a (braced) string literal is a special case; the init
1102 // list element does not initialize a (single) array element.
1103 if ((ile && ile->isStringLiteralInit()) || sl || ocee) {
1104 if (!ile)
1105 init = ignoreParen;
1106
1107 // Initialize the initial portion of length equal to that of the string
1108 // literal. The allocation must be for at least this much; we emitted a
1109 // check for that earlier. Since we intend to use a cir.copy here, we must
1110 // introduce a cast to the string-literal-size here, so that cir.copy does
1111 // the right thing.
1112
1113 const Expr *initExpr = ile ? ile->getInit(0) : init;
1114 mlir::Type initExprTy = convertType(initExpr->getType());
1115 Address coercedPtr = curPtr.withElementType(builder, initExprTy);
1116
1118 coercedPtr, elementType.getQualifiers(), AggValueSlot::IsDestructed,
1123 emitAggExpr(initExpr, slot);
1124
1125 // Move past these elements.
1126 initListElements =
1128 ->getZExtSize();
1129
1130 bool alreadyInitedAll = false;
1131 auto constElts = numElements.getDefiningOp<cir::ConstantOp>();
1132 if (constElts) {
1133 int64_t constVal = getZExtIntValueFromConstOp(numElements);
1134 alreadyInitedAll = (constVal == initListElements);
1135 }
1136
1137 // Init the rest with memset, unless we've already done everything.
1138 if (!alreadyInitedAll) {
1139 mlir::Location initLoc = cgm.getLoc(init->getSourceRange());
1140 mlir::Value initListElementsOp = builder.getUnsignedInt(
1141 initLoc, initListElements,
1142 getContext().getTypeSize(getContext().getSizeType()));
1143 curPtr = curPtr.withPointer(builder.createPtrStride(
1144 initLoc, curPtr.getPointer(), initListElementsOp));
1145
1146 bool ok = tryMemsetInitialization();
1147 (void)ok;
1148 assert(ok && "couldn't memset character type?");
1149 }
1150 return;
1151 }
1152
1153 ArrayRef<const Expr *> initExprs =
1154 ile ? ile->inits() : cplie->getInitExprs();
1155 initListElements = initExprs.size();
1156
1157 // If this is a multi-dimensional array new, we will initialize multiple
1158 // elements with each init list element.
1159 QualType allocType = e->getAllocatedType();
1160 if (const ConstantArrayType *cat = dyn_cast_or_null<ConstantArrayType>(
1161 allocType->getAsArrayTypeUnsafe())) {
1162 elementTy = convertTypeForMem(allocType);
1163 curPtr = curPtr.withElementType(builder, elementTy);
1164 initListElements *= getContext().getConstantArrayElementCount(cat);
1165 }
1166
1167 // Enter a partial-destruction Cleanup if necessary.
1168 CharUnits elementSize = getContext().getTypeSizeInChars(elementType);
1169 if (dtorKind) {
1170 mlir::Location loc = cgm.getLoc(init->getSourceRange());
1171 endOfInit = createTempAlloca(beginPtr.getType(), getPointerAlign(), loc,
1172 "arrayinit.endOfInit");
1174 beginPtr.getPointer(), endOfInit, elementType,
1175 beginPtr.getAlignment().alignmentOfArrayElement(elementSize),
1176 getDestroyer(dtorKind));
1177 }
1178
1179 CharUnits startAlign = curPtr.getAlignment();
1180 unsigned i = 0;
1181 for (const Expr *ie : initExprs) {
1182 mlir::Location loc = getLoc(ie->getExprLoc());
1183
1184 // Tell the cleanup that it needs to destroy up to this
1185 // element. TODO: some of these stores can be trivially
1186 // observed to be unnecessary.
1187 if (endOfInit.isValid())
1188 builder.createStore(loc, curPtr.getPointer(), endOfInit);
1189
1190 // FIXME: If the last initializer is an incomplete initializer list for
1191 // an array, and we have an array filler, we can fold together the two
1192 // initialization loops.
1193 storeAnyExprIntoOneUnit(*this, ie, ie->getType(), curPtr,
1195 mlir::Value castOp = builder.createPtrBitcast(
1196 curPtr.getPointer(), convertTypeForMem(allocType));
1197 mlir::Value offsetOp = builder.getSignedInt(loc, 1, /*width=*/32);
1198 mlir::Value dataPtr = builder.createPtrStride(loc, castOp, offsetOp);
1199 curPtr = Address(dataPtr, curPtr.getElementType(),
1200 startAlign.alignmentAtOffset((++i) * elementSize));
1201 }
1202
1203 // The remaining elements are filled with the array filler expression.
1204 init = ile ? ile->getArrayFiller() : cplie->getArrayFiller();
1205
1206 // Extract the initializer for the individual array elements by pulling
1207 // out the array filler from all the nested initializer lists. This avoids
1208 // generating a nested loop for the initialization.
1209 while (init && init->getType()->isConstantArrayType()) {
1210 auto *subIle = dyn_cast<InitListExpr>(init);
1211 if (!subIle)
1212 break;
1213 assert(subIle->getNumInits() == 0 && "explicit inits in array filler?");
1214 init = subIle->getArrayFiller();
1215 }
1216
1217 // Switch back to initializing one base element at a time.
1218 curPtr = curPtr.withElementType(builder, beginPtr.getElementType());
1219 }
1220
1221 // If all elements have already been initialized, skip any further
1222 // initialization.
1223 auto constOp = mlir::dyn_cast<cir::ConstantOp>(numElements.getDefiningOp());
1224 if (constOp) {
1225 auto constIntAttr = mlir::dyn_cast<cir::IntAttr>(constOp.getValue());
1226 // Just skip out if the constant count is zero.
1227 if (constIntAttr && constIntAttr.getUInt() <= initListElements)
1228 return;
1229 }
1230
1231 assert(init && "have trailing elements to initialize but no initializer");
1232
1233 // If this is a constructor call, try to optimize it out, and failing that
1234 // emit a single loop to initialize all remaining elements.
1235 if (const CXXConstructExpr *cce = dyn_cast<CXXConstructExpr>(init)) {
1236 CXXConstructorDecl *ctor = cce->getConstructor();
1237 if (ctor->isTrivial()) {
1238 // If new expression did not specify value-initialization, then there
1239 // is no initialization.
1240 if (!cce->requiresZeroInitialization() || ctor->getParent()->isEmpty())
1241 return;
1242
1243 if (tryMemsetInitialization())
1244 return;
1245 }
1246
1247 // Store the new Cleanup position for irregular Cleanups.
1248 //
1249 // FIXME: Share this cleanup with the constructor call emission rather than
1250 // having it create a cleanup of its own.
1251 if (endOfInit.isValid())
1252 builder.createStore(getLoc(e->getSourceRange()), curPtr.emitRawPointer(),
1253 endOfInit);
1254
1255 mlir::Type initType = convertType(cce->getType());
1256 // Emit a constructor call loop to initialize the remaining elements.
1257 if (initListElements) {
1258 // If the number of elements is a constant, we will have already gotten
1259 // the constant op above. Here we use it to get the number of remaining
1260 // elements as a new constant.
1261 if (constOp) {
1262 auto constIntAttr = mlir::cast<cir::IntAttr>(constOp.getValue());
1263 uint64_t numRemainingElements =
1264 constIntAttr.getUInt() - initListElements;
1265 numElements =
1266 builder.getConstInt(getLoc(e->getSourceRange()),
1267 numElements.getType(), numRemainingElements);
1268 // Currently, the AST gives us a pointer to the element type here
1269 // rather than an array. That's inconsistent with what it does
1270 // without an explicit initializer list, so we need to create an
1271 // array type here. That will decay back to a pointer when we lower
1272 // the cir.array.ctor op, but we need an array type for the initial
1273 // representation.
1274 if (!mlir::isa<cir::ArrayType>(initType))
1275 initType = cir::ArrayType::get(initType, numRemainingElements);
1276 } else {
1277 cgm.errorNYI(e->getSourceRange(),
1278 "emitNewArrayInitializer: numRemainingElements with "
1279 "non-constant count");
1280 return;
1281 }
1282 }
1283
1284 curPtr = curPtr.withElementType(builder, initType);
1285 emitCXXAggrConstructorCall(ctor, numElements, curPtr, cce,
1286 /*newPointerIsChecked=*/true,
1287 cce->requiresZeroInitialization(), endOfInit);
1288 if (getContext().getTargetInfo().emitVectorDeletingDtors(
1289 getContext().getLangOpts())) {
1290 cgm.errorNYI(e->getSourceRange(),
1291 "emitNewArrayInitializer: emitVectorDeletingDtors");
1292 }
1293 return;
1294 }
1295
1296 // If this is value-initialization, we can usually use memset.
1297 ImplicitValueInitExpr ivie(elementType);
1298 if (isa<ImplicitValueInitExpr>(init)) {
1299 if (tryMemsetInitialization())
1300 return;
1301 // Switch to an ImplicitValueInitExpr for the element type. This handles
1302 // only one case: multidimensional array new of pointers to members. In
1303 // all other cases, we already have an initializer for the array element.
1304 init = &ivie;
1305 }
1306
1307 // At this point we should have found an initializer for the individual
1308 // elements of the array.
1309 assert(getContext().hasSameUnqualifiedType(elementType, init->getType()) &&
1310 "got wrong type of element to initialize");
1311
1312 // If we have a struct whose every field is value-initialized, we can
1313 // usually use memset.
1314 if (auto *ile = dyn_cast<InitListExpr>(init)) {
1315
1316 // If we have an empty initializer list, we can usually use memset.
1317 if (ile->getNumInits() == 0 && tryMemsetInitialization())
1318 return;
1319
1320 if (const auto *rtype = ile->getType()->getAsCanonical<RecordType>()) {
1321 if (rtype->getDecl()->isStruct()) {
1322 const RecordDecl *rd = rtype->getDecl()->getDefinitionOrSelf();
1323 unsigned numElements = 0;
1324 if (auto *cxxrd = dyn_cast<CXXRecordDecl>(rd))
1325 numElements = cxxrd->getNumBases();
1326 for (FieldDecl *field : rd->fields())
1327 if (!field->isUnnamedBitField())
1328 ++numElements;
1329 // FIXME: Recurse into nested InitListExprs.
1330 if (ile->getNumInits() == numElements)
1331 for (unsigned i = 0, e = ile->getNumInits(); i != e; ++i)
1332 if (!isa<ImplicitValueInitExpr>(ile->getInit(i)))
1333 --numElements;
1334 if (ile->getNumInits() == numElements && tryMemsetInitialization())
1335 return;
1336 }
1337 }
1338 }
1339
1340 // The rest of this has to go through the rest of the initializer, generating
1341 // a loop with cleanups/destruction/etc. See the test
1342 // 'check_array_value_init'(currently disabled) in
1343 // CodeGenCXX/new-array-init.cpp when we get more of this implemented.
1344 cgm.errorNYI(init->getSourceRange(),
1345 "emitNewArrayInitializer: unsupported initializer");
1346 return;
1347}
1348
1350 QualType elementType, mlir::Type elementTy,
1351 Address newPtr, mlir::Value numElements,
1352 mlir::Value allocSizeWithoutCookie) {
1354 if (e->isArray()) {
1355 cgf.emitNewArrayInitializer(e, elementType, elementTy, newPtr, numElements,
1356 allocSizeWithoutCookie);
1357 } else if (const Expr *init = e->getInitializer()) {
1358 storeAnyExprIntoOneUnit(cgf, init, e->getAllocatedType(), newPtr,
1360 }
1361}
1362
1364 GlobalDecl dtor, const CIRGenCallee &callee, mlir::Value thisVal,
1365 QualType thisTy, mlir::Value implicitParam, QualType implicitParamTy,
1366 const CallExpr *ce) {
1367 const CXXMethodDecl *dtorDecl = cast<CXXMethodDecl>(dtor.getDecl());
1368
1369 assert(!thisTy.isNull());
1370 assert(thisTy->getAsCXXRecordDecl() == dtorDecl->getParent() &&
1371 "Pointer/Object mixup");
1372
1374
1375 CallArgList args;
1376 commonBuildCXXMemberOrOperatorCall(*this, dtorDecl, thisVal, implicitParam,
1377 implicitParamTy, ce, args, nullptr);
1378 assert((ce || dtor.getDecl()) && "expected source location provider");
1379 return emitCall(cgm.getTypes().arrangeCXXStructorDeclaration(dtor), callee,
1380 ReturnValueSlot(), args, nullptr, ce && ce == mustTailCall,
1381 ce ? ce->getSourceRange() : dtor.getDecl()->getSourceRange());
1382}
1383
1386 QualType destroyedType = expr->getDestroyedType();
1387 if (destroyedType.hasStrongOrWeakObjCLifetime()) {
1389 cgm.errorNYI(expr->getExprLoc(),
1390 "emitCXXPseudoDestructorExpr: Objective-C lifetime is NYI");
1391 } else {
1392 // C++ [expr.pseudo]p1:
1393 // The result shall only be used as the operand for the function call
1394 // operator (), and the result of such a call has type void. The only
1395 // effect is the evaluation of the postfix-expression before the dot or
1396 // arrow.
1397 emitIgnoredExpr(expr->getBase());
1398 }
1399
1400 return RValue::get(nullptr);
1401}
1402
1403namespace {
1404/// Calls the given 'operator delete' on a single object.
1405struct CallObjectDelete final : EHScopeStack::Cleanup {
1406 mlir::Value ptr;
1407 const FunctionDecl *operatorDelete;
1408 QualType elementType;
1409
1410 CallObjectDelete(mlir::Value ptr, const FunctionDecl *operatorDelete,
1411 QualType elementType)
1412 : ptr(ptr), operatorDelete(operatorDelete), elementType(elementType) {}
1413
1414 void emit(CIRGenFunction &cgf, Flags flags) override {
1415 cgf.emitDeleteCall(operatorDelete, ptr, elementType);
1416 }
1417};
1418} // namespace
1419
1420/// Emit the code for deleting a single object via a destroying operator
1421/// delete. If the element type has a non-virtual destructor, Ptr has already
1422/// been converted to the type of the parameter of 'operator delete'. Otherwise
1423/// Ptr points to an object of the static type.
1425 const CXXDeleteExpr *de, Address ptr,
1426 QualType elementType) {
1427 const CXXDestructorDecl *dtor =
1428 elementType->getAsCXXRecordDecl()->getDestructor();
1429 if (dtor && dtor->isVirtual()) {
1430 cgf.cgm.getCXXABI().emitVirtualObjectDelete(cgf, de, ptr, elementType,
1431 dtor);
1432 return;
1433 }
1434
1435 cgf.emitDeleteCall(de->getOperatorDelete(), ptr.getPointer(), elementType);
1436}
1437
1438/// Emit the code for deleting a single object.
1440 Address ptr, QualType elementType) {
1441 // C++11 [expr.delete]p3:
1442 // If the static type of the object to be deleted is different from its
1443 // dynamic type, the static type shall be a base class of the dynamic type
1444 // of the object to be deleted and the static type shall have a virtual
1445 // destructor or the behavior is undefined.
1447
1448 const FunctionDecl *operatorDelete = de->getOperatorDelete();
1449 assert(!operatorDelete->isDestroyingOperatorDelete());
1450
1451 // Find the destructor for the type, if applicable. If the
1452 // destructor is virtual, we'll just emit the vcall and return.
1453 const CXXDestructorDecl *dtor = nullptr;
1454 if (const auto *rd = elementType->getAsCXXRecordDecl()) {
1455 if (rd->hasDefinition() && !rd->hasTrivialDestructor()) {
1456 dtor = rd->getDestructor();
1457
1458 if (dtor->isVirtual()) {
1460 cgf.cgm.getCXXABI().emitVirtualObjectDelete(cgf, de, ptr, elementType,
1461 dtor);
1462 return;
1463 }
1464 }
1465 }
1466
1467 // Make sure that we call delete even if the dtor throws.
1468 // This doesn't have to a conditional cleanup because we're going
1469 // to pop it off in a second.
1470 cgf.ehStack.pushCleanup<CallObjectDelete>(
1471 NormalAndEHCleanup, ptr.getPointer(), operatorDelete, elementType);
1472
1473 if (dtor) {
1475 /*ForVirtualBase=*/false,
1476 /*Delegating=*/false, ptr, elementType);
1477 } else if (elementType.getObjCLifetime()) {
1479 cgf.cgm.errorNYI(de->getSourceRange(), "emitObjectDelete: ObjCLifetime");
1480 }
1481
1482 cgf.popCleanupBlock();
1483}
1484
1486 const Expr *arg = e->getArgument();
1488
1489 // Null check the pointer.
1490 //
1491 // We could avoid this null check if we can determine that the object
1492 // destruction is trivial and doesn't require an array cookie; we can
1493 // unconditionally perform the operator delete call in that case. For now, we
1494 // assume that deleted pointers are null rarely enough that it's better to
1495 // keep the branch. This might be worth revisiting for a -O0 code size win.
1497 cir::YieldOp thenYield;
1498 mlir::Value notNull = builder.createPtrIsNotNull(ptr.getPointer());
1499 cir::IfOp::create(builder, getLoc(e->getExprLoc()), notNull,
1500 /*withElseRegion=*/false,
1501 /*thenBuilder=*/
1502 [&](mlir::OpBuilder &b, mlir::Location loc) {
1503 thenYield = builder.createYield(loc);
1504 });
1505
1506 // Emit the rest of the CIR inside the if-op's then region, but restore the
1507 // insertion point to the point after the if when this function returns.
1508 mlir::OpBuilder::InsertionGuard guard(builder);
1509 builder.setInsertionPoint(thenYield);
1510
1511 QualType deleteTy = e->getDestroyedType();
1512
1513 // A destroying operator delete overrides the entire operation of the
1514 // delete expression.
1516 emitDestroyingObjectDelete(*this, e, ptr, deleteTy);
1517 return;
1518 }
1519
1520 // We might be deleting a pointer to array.
1521 deleteTy = getContext().getBaseElementType(deleteTy);
1522 ptr = ptr.withElementType(builder, convertTypeForMem(deleteTy));
1523
1524 if (e->isArrayForm() &&
1525 cgm.getASTContext().getTargetInfo().emitVectorDeletingDtors(
1526 cgm.getASTContext().getLangOpts())) {
1527 cgm.errorNYI(e->getSourceRange(),
1528 "emitCXXDeleteExpr: emitVectorDeletingDtors");
1529 }
1530
1531 if (e->isArrayForm()) {
1532 const FunctionDecl *operatorDelete = e->getOperatorDelete();
1533 cir::FuncOp operatorDeleteFn = cgm.getAddrOfFunction(operatorDelete);
1534 auto deleteFn =
1535 mlir::FlatSymbolRefAttr::get(operatorDeleteFn.getSymNameAttr());
1536 UsualDeleteParams udp = operatorDelete->getUsualDeleteParams();
1537 std::optional<uint64_t> align;
1538
1539 if (isAlignedAllocation(udp.Alignment)) {
1540 CharUnits elementSize = cgm.getASTContext().getTypeSizeInChars(deleteTy);
1541 align =
1543 }
1544
1545 cir::UsualDeleteParamsAttr deleteParams;
1546 if (udp.Size || align || isTypeAwareAllocation(udp.TypeAwareDelete) ||
1547 udp.DestroyingDelete)
1548 deleteParams = cir::UsualDeleteParamsAttr::get(
1549 builder.getContext(), udp.Size, align,
1551
1552 // Alignment of the element, used for the 'cookie' later.
1553 uint64_t elementAlign = cgm.getASTContext()
1554 .getPreferredTypeAlignInChars(deleteTy)
1555 .getQuantity();
1556
1557 mlir::FlatSymbolRefAttr elementDtor;
1558 bool hasThrowingDtor = false;
1559 if (const auto *rd = deleteTy->getAsCXXRecordDecl()) {
1560 if (rd->hasDefinition() && !rd->hasTrivialDestructor()) {
1561 const CXXDestructorDecl *dtor = rd->getDestructor();
1562 if (dtor->getType()->castAs<FunctionProtoType>()->canThrow())
1563 hasThrowingDtor = true;
1564 cir::FuncOp dtorFn =
1565 cgm.getAddrOfCXXStructor(GlobalDecl(dtor, Dtor_Complete));
1566 elementDtor = mlir::FlatSymbolRefAttr::get(builder.getContext(),
1567 dtorFn.getSymNameAttr());
1568 }
1569 }
1570
1571 cir::DeleteArrayOp::create(builder, ptr.getPointer().getLoc(),
1572 ptr.getPointer(), deleteFn, deleteParams,
1573 elementDtor, hasThrowingDtor,
1574 builder.getI64IntegerAttr(elementAlign));
1575 } else {
1576 emitObjectDelete(*this, e, ptr, deleteTy);
1577 }
1578}
1579
1581 // The element type being allocated.
1583
1584 // 1. Build a call to the allocation function.
1585 FunctionDecl *allocator = e->getOperatorNew();
1586
1587 // If there is a brace-initializer, cannot allocate fewer elements than inits.
1588 unsigned minElements = 0;
1589 if (e->isArray() && e->hasInitializer()) {
1590 const Expr *init = e->getInitializer();
1591 const InitListExpr *ile = dyn_cast<InitListExpr>(init);
1592 const CXXParenListInitExpr *cplie = dyn_cast<CXXParenListInitExpr>(init);
1593 const Expr *ignoreParen = init->IgnoreParenImpCasts();
1594 if ((ile && ile->isStringLiteralInit()) ||
1595 isa<StringLiteral>(ignoreParen) || isa<ObjCEncodeExpr>(ignoreParen)) {
1596 minElements =
1598 ->getSize()
1599 .getZExtValue();
1600 } else if (ile || cplie) {
1601 minElements = ile ? ile->getNumInits() : cplie->getInitExprs().size();
1602 }
1603 }
1604
1605 mlir::Value numElements = nullptr;
1606 mlir::Value allocSizeWithoutCookie = nullptr;
1607 mlir::Value allocSize = emitCXXNewAllocSize(
1608 *this, e, minElements, numElements, allocSizeWithoutCookie);
1609 CharUnits allocAlign = getContext().getTypeAlignInChars(allocType);
1610
1611 // Emit the allocation call.
1612 Address allocation = Address::invalid();
1613 CallArgList allocatorArgs;
1614 if (allocator->isReservedGlobalPlacementOperator()) {
1615 // If the allocator is a global placement operator, just
1616 // "inline" it directly.
1617 assert(e->getNumPlacementArgs() == 1);
1618 const Expr *arg = *e->placement_arguments().begin();
1619
1620 LValueBaseInfo baseInfo;
1621 allocation = emitPointerWithAlignment(arg, &baseInfo);
1622
1623 // The pointer expression will, in many cases, be an opaque void*.
1624 // In these cases, discard the computed alignment and use the
1625 // formal alignment of the allocated type.
1626 if (baseInfo.getAlignmentSource() != AlignmentSource::Decl)
1627 allocation = allocation.withAlignment(allocAlign);
1628
1629 // Set up allocatorArgs for the call to operator delete if it's not
1630 // the reserved global operator.
1631 if (e->getOperatorDelete() &&
1633 cgm.errorNYI(e->getSourceRange(),
1634 "emitCXXNewExpr: reserved placement new with delete");
1635 }
1636 } else {
1637 const FunctionProtoType *allocatorType =
1638 allocator->getType()->castAs<FunctionProtoType>();
1639 unsigned paramsToSkip = 0;
1640
1641 // The allocation size is the first argument.
1642 QualType sizeType = getContext().getSizeType();
1643 allocatorArgs.add(RValue::get(allocSize), sizeType);
1644 ++paramsToSkip;
1645
1646 if (allocSize != allocSizeWithoutCookie) {
1647 CharUnits cookieAlign = getSizeAlign(); // FIXME: Ask the ABI.
1648 allocAlign = std::max(allocAlign, cookieAlign);
1649 }
1650
1651 // The allocation alignment may be passed as the second argument.
1652 if (e->passAlignment()) {
1653 // The alignment is always the second positional argument to a
1654 // C++17 aligned allocation function -- right after the size.
1655 constexpr unsigned indexOfAlignArg = 1;
1656 // The corresponding parameter type, if the allocator declares one;
1657 // otherwise fall back to size_t (the underlying type of
1658 // std::align_val_t).
1659 QualType alignValType = sizeType;
1660 if (allocatorType->getNumParams() > indexOfAlignArg)
1661 alignValType = allocatorType->getParamType(indexOfAlignArg);
1662 cir::ConstantOp align = builder.getAlignment(
1663 getLoc(*currSrcLoc), convertType(alignValType), allocAlign);
1664 allocatorArgs.add(RValue::get(align), alignValType);
1665 ++paramsToSkip;
1666 }
1667
1668 // FIXME: Why do we not pass a CalleeDecl here?
1669 emitCallArgs(allocatorArgs, allocatorType, e->placement_arguments(),
1670 AbstractCallee(), paramsToSkip);
1671 RValue rv =
1672 emitNewDeleteCall(*this, allocator, allocatorType, allocatorArgs);
1673
1674 // Set !heapallocsite metadata on the call to operator new.
1676
1677 // If this was a call to a global replaceable allocation function that does
1678 // not take an alignment argument, the allocator is known to produce storage
1679 // that's suitably aligned for any object that fits, up to a known
1680 // threshold. Otherwise assume it's suitably aligned for the allocated type.
1681 CharUnits allocationAlign = allocAlign;
1682 if (!e->passAlignment() &&
1683 allocator->isReplaceableGlobalAllocationFunction()) {
1684 const TargetInfo &target = cgm.getASTContext().getTargetInfo();
1685 unsigned allocatorAlign = llvm::bit_floor(std::min<uint64_t>(
1686 target.getNewAlign(), getContext().getTypeSize(allocType)));
1687 allocationAlign = std::max(
1688 allocationAlign, getContext().toCharUnitsFromBits(allocatorAlign));
1689 }
1690
1691 mlir::Value allocPtr = rv.getValue();
1692 allocation = Address(
1693 allocPtr, mlir::cast<cir::PointerType>(allocPtr.getType()).getPointee(),
1694 allocationAlign);
1695 }
1696
1697 // Emit a null check on the allocation result if the allocation
1698 // function is allowed to return null (because it has a non-throwing
1699 // exception spec or is the reserved placement new) and we have an
1700 // interesting initializer will be running sanitizers on the initialization.
1701 bool nullCheck = e->shouldNullCheckAllocation() &&
1702 (!allocType.isPODType(getContext()) || e->hasInitializer());
1703
1704 // If there's an operator delete, enter a cleanup to call it if an
1705 // exception is thrown. If we do this, we'll be creating the result pointer
1706 // inside a cleanup scope, either with a bitcast or an offset based on the
1707 // array cookie size. However, we need to return that pointer from outside
1708 // the cleanup scope, so we need to store it in a temporary variable.
1709 bool useNewDeleteCleanup =
1710 e->getOperatorDelete() &&
1712
1713 mlir::Type elementTy;
1714 // For array new, use the allocated type to handle multidimensional arrays
1715 // correctly.
1716 if (e->isArray())
1717 elementTy = convertTypeForMem(e->getAllocatedType());
1718 else
1719 elementTy = convertTypeForMem(allocType);
1720
1721 // Lambda that emits the init sequence: cleanup setup, cookie init,
1722 // bitcast + initializer, and cleanup deactivation.
1723 //
1724 // \p conditional is non-null when this new-expression is null-checked.
1725 // ConditionalEvaluation is activated only around emitNewInitializer so that
1726 // temporaries created there get conditional cleanups, while the operator
1727 // delete cleanup (which is entered and left entirely inside the null-check
1728 // branch) stays on the cheaper unconditional path.
1729 Address result = Address::invalid();
1730 Address resultPtr = Address::invalid();
1731 auto emitInit = [&](ConditionalEvaluation *conditional) {
1732 EHScopeStack::stable_iterator operatorDeleteCleanup;
1733 mlir::Operation *cleanupDominator = nullptr;
1734 if (useNewDeleteCleanup) {
1736 enterNewDeleteCleanup(*this, e, allocation, allocSize, allocAlign,
1737 allocatorArgs);
1738 operatorDeleteCleanup = ehStack.stable_begin();
1739 cleanupDominator =
1740 cir::UnreachableOp::create(builder, getLoc(e->getSourceRange()))
1741 .getOperation();
1742 resultPtr = createTempAlloca(builder.getPointerTo(elementTy),
1743 allocation.getAlignment(),
1744 getLoc(e->getSourceRange()), "__new_result");
1745 }
1746
1747 if (allocSize != allocSizeWithoutCookie) {
1748 assert(e->isArray());
1749 allocation = cgm.getCXXABI().initializeArrayCookie(
1750 *this, allocation, numElements, e, allocType);
1751 }
1752
1753 result = builder.createElementBitCast(getLoc(e->getSourceRange()),
1754 allocation, elementTy);
1755
1756 // Store the result pointer before initialization so that it is available
1757 // to the cleanup if the initializer throws.
1758 if (resultPtr.isValid())
1759 builder.createStore(getLoc(e->getSourceRange()), result.getPointer(),
1760 resultPtr);
1761
1762 // Passing pointer through launder.invariant.group to avoid propagation of
1763 // vptrs information which may be included in previous type. To not break
1764 // LTO with different optimizations levels, we do it regardless of
1765 // optimization level.
1766 if (cgm.getCodeGenOpts().StrictVTablePointers &&
1767 allocator->isReservedGlobalPlacementOperator())
1768 cgm.errorNYI(e->getSourceRange(),
1769 "emitCXXNewExpr: strict vtable pointers");
1770
1772
1773 if (conditional)
1774 conditional->beginEvaluation();
1775 emitNewInitializer(*this, e, allocType, elementTy, result, numElements,
1776 allocSizeWithoutCookie);
1777 if (conditional)
1778 conditional->endEvaluation();
1779
1780 // Deactivate the 'operator delete' cleanup if we finished
1781 // initialization.
1782 if (useNewDeleteCleanup) {
1783 deactivateCleanupBlock(operatorDeleteCleanup, cleanupDominator);
1784 cleanupDominator->erase();
1785 cir::LoadOp loadResult =
1786 builder.createLoad(getLoc(e->getSourceRange()), resultPtr);
1787 result = result.withPointer(loadResult.getResult());
1788 }
1789 };
1790
1791 cir::IfOp nullCheckOp;
1792 if (nullCheck) {
1793 // The initializer is only run if the allocation succeeds, so any
1794 // temporaries created while emitting the initializer must be cleaned up
1795 // conditionally (with an active flag) after the branch. The enclosing
1796 // FullExprCleanupScope detects this via ConditionalEvaluationFinder and
1797 // provides the cleanup region for the deferred destructors.
1798 mlir::Value isNotNull = builder.createPtrIsNotNull(allocation.getPointer());
1799
1800 ConditionalEvaluation eval(*this, getLoc(e->getSourceRange()));
1801 nullCheckOp =
1802 cir::IfOp::create(builder, getLoc(e->getSourceRange()), isNotNull,
1803 /*withElseRegion=*/false,
1804 /*thenBuilder=*/
1805 [&](mlir::OpBuilder &, mlir::Location loc) {
1806 emitInit(&eval);
1807 builder.createYield(loc);
1808 });
1809 } else {
1810 emitInit(/*conditional=*/nullptr);
1811 }
1812
1813 mlir::Value resultValue = result.getPointer();
1814
1815 if (nullCheck) {
1816 mlir::Type resultTy = resultValue.getType();
1817
1818 // If we needed a NewDeleteCleanup, allocation may have been modified
1819 // inside the cir.if (e.g. by cookie adjustment). Use the result stored
1820 // in the alloca instead, since the alloca dominates this point.
1821 mlir::Value trueVal;
1822 if (useNewDeleteCleanup) {
1823 trueVal = builder.createLoad(getLoc(e->getSourceRange()), resultPtr)
1824 .getResult();
1825 } else {
1826 trueVal = allocation.getPointer();
1827 }
1828 if (trueVal.getType() != resultTy)
1829 trueVal = builder.createBitcast(trueVal, resultTy);
1830 mlir::Value nullPtr =
1831 builder.getNullPtr(resultTy, getLoc(e->getSourceRange())).getResult();
1832 resultValue =
1833 builder.createSelect(getLoc(e->getSourceRange()),
1834 nullCheckOp.getCondition(), trueVal, nullPtr);
1835 }
1836
1837 return resultValue;
1838}
1839
1841 mlir::Value ptr, QualType deleteTy) {
1843
1844 const auto *deleteFTy = deleteFD->getType()->castAs<FunctionProtoType>();
1845 CallArgList deleteArgs;
1846
1847 UsualDeleteParams params = deleteFD->getUsualDeleteParams();
1848 auto paramTypeIter = deleteFTy->param_type_begin();
1849
1850 // Pass std::type_identity tag if present
1852 cgm.errorNYI(deleteFD->getSourceRange(),
1853 "emitDeleteCall: type aware delete");
1854
1855 // Pass the pointer itself.
1856 QualType argTy = *paramTypeIter;
1857 std::advance(paramTypeIter, 1);
1858 mlir::Value deletePtr =
1859 builder.createBitcast(ptr.getLoc(), ptr, convertType(argTy));
1860 deleteArgs.add(RValue::get(deletePtr), argTy);
1861
1862 // Pass the std::destroying_delete tag if present.
1863 if (params.DestroyingDelete) {
1864 QualType tagType = *paramTypeIter;
1865 std::advance(paramTypeIter, 1);
1866 Address tagAddr =
1867 createMemTemp(tagType, ptr.getLoc(), "destroying.delete.tag");
1868 deleteArgs.add(RValue::getAggregate(tagAddr), tagType);
1869 }
1870
1871 // Pass the size if the delete function has a size_t parameter.
1872 if (params.Size) {
1873 QualType sizeType = *paramTypeIter;
1874 std::advance(paramTypeIter, 1);
1875 CharUnits deleteTypeSize = getContext().getTypeSizeInChars(deleteTy);
1876 assert(mlir::isa<cir::IntType>(convertType(sizeType)) &&
1877 "expected cir::IntType");
1878 cir::ConstantOp size =
1879 builder.getConstInt(getLoc(*currSrcLoc), convertType(sizeType),
1880 deleteTypeSize.getQuantity());
1881
1882 deleteArgs.add(RValue::get(size), sizeType);
1883 }
1884
1885 // Pass the alignment if the delete function has an align_val_t parameter.
1886 if (isAlignedAllocation(params.Alignment)) {
1887 QualType alignValType = *paramTypeIter++;
1888 CharUnits deleteTypeAlign =
1889 getContext().toCharUnitsFromBits(getContext().getTypeAlignIfKnown(
1890 deleteTy, /*NeedsPreferredAlignment=*/true));
1891 cir::ConstantOp align = builder.getAlignment(
1892 getLoc(*currSrcLoc), convertType(alignValType), deleteTypeAlign);
1893 deleteArgs.add(RValue::get(align), alignValType);
1894 }
1895
1896 assert(paramTypeIter == deleteFTy->param_type_end() &&
1897 "unknown parameter to usual delete function");
1898
1899 // Emit the call to delete.
1900 emitNewDeleteCall(*this, deleteFD, deleteFTy, deleteArgs);
1901}
1902
1904 mlir::Location loc, QualType destTy) {
1905 mlir::Type destCIRTy = cgf.convertType(destTy);
1906 assert(mlir::isa<cir::PointerType>(destCIRTy) &&
1907 "result of dynamic_cast should be a ptr");
1908
1909 if (!destTy->isPointerType()) {
1910 mlir::Region *currentRegion = cgf.getBuilder().getBlock()->getParent();
1911 /// C++ [expr.dynamic.cast]p9:
1912 /// A failed cast to reference type throws std::bad_cast
1913 cgf.cgm.getCXXABI().emitBadCastCall(cgf, loc);
1914
1915 // The call to bad_cast will terminate the current block. Create a new block
1916 // to hold any follow up code.
1917 cgf.getBuilder().createBlock(currentRegion, currentRegion->end());
1918 }
1919
1920 return cgf.getBuilder().getNullPtr(destCIRTy, loc);
1921}
1922
1924 const CXXDynamicCastExpr *dce) {
1925 mlir::Location loc = getLoc(dce->getSourceRange());
1926
1927 cgm.emitExplicitCastExprType(dce, this);
1928 QualType destTy = dce->getTypeAsWritten();
1929 QualType srcTy = dce->getSubExpr()->getType();
1930
1931 // C++ [expr.dynamic.cast]p7:
1932 // If T is "pointer to cv void," then the result is a pointer to the most
1933 // derived object pointed to by v.
1934 bool isDynCastToVoid = destTy->isVoidPointerType();
1935 bool isRefCast = destTy->isReferenceType();
1936
1937 QualType srcRecordTy;
1938 QualType destRecordTy;
1939 if (isDynCastToVoid) {
1940 srcRecordTy = srcTy->getPointeeType();
1941 // No destRecordTy.
1942 } else if (const PointerType *destPTy = destTy->getAs<PointerType>()) {
1943 srcRecordTy = srcTy->castAs<PointerType>()->getPointeeType();
1944 destRecordTy = destPTy->getPointeeType();
1945 } else {
1946 srcRecordTy = srcTy;
1947 destRecordTy = destTy->castAs<ReferenceType>()->getPointeeType();
1948 }
1949
1950 assert(srcRecordTy->isRecordType() && "source type must be a record type!");
1952
1953 if (dce->isAlwaysNull())
1954 return emitDynamicCastToNull(*this, loc, destTy);
1955
1956 auto destCirTy = mlir::cast<cir::PointerType>(convertType(destTy));
1957 return cgm.getCXXABI().emitDynamicCast(*this, loc, srcRecordTy, destRecordTy,
1958 destCirTy, isRefCast, thisAddr);
1959}
1960
1962 bool hasNullCheck) {
1963 Address thisPtr = cgf.emitLValue(e).getAddress();
1964 QualType srcType = e->getType();
1965
1966 // C++ [class.cdtor]p4:
1967 // If the operand of typeid refers to the object under construction or
1968 // destruction and the static type of the operand is neither the constructor
1969 // or destructor’s class nor one of its bases, the behavior is undefined.
1971
1972 if (hasNullCheck && cgf.cgm.getCXXABI().shouldTypeidBeNullChecked(srcType)) {
1973 mlir::Value isThisNull =
1974 cgf.getBuilder().createPtrIsNull(thisPtr.getPointer());
1975 // We don't really care about the value, we just want to make sure the
1976 // 'true' side calls bad-type-id.
1977 cir::IfOp::create(
1978 cgf.getBuilder(), cgf.getLoc(e->getSourceRange()), isThisNull,
1979 /*withElseRegion=*/false, [&](mlir::OpBuilder &, mlir::Location loc) {
1980 cgf.cgm.getCXXABI().emitBadTypeidCall(cgf, loc);
1981 });
1982 }
1983
1984 return thisPtr;
1985}
1986
1988 mlir::Location loc = getLoc(e->getSourceRange());
1989 mlir::Type resultType = cir::PointerType::get(convertType(e->getType()));
1991 : e->getExprOperand()->getType();
1992
1993 // If the non-default global var address space is not default, we need to do
1994 // an address-space cast here.
1996
1997 // C++ [expr.typeid]p2:
1998 // When typeid is applied to a glvalue expression whose type is a
1999 // polymorphic class type, the result refers to a std::type_info object
2000 // representing the type of the most derived object (that is, the dynamic
2001 // type) to which the glvalue refers.
2002 if (!e->isTypeOperand() && e->isPotentiallyEvaluated()) {
2003 Address thisPtr =
2005 if (!e->isMostDerived(getContext()))
2006 return cgm.getCXXABI().emitTypeid(*this, ty, thisPtr, resultType);
2007 // If the operand is already most derived object, no need to look up vtable.
2008 }
2009
2010 auto typeInfo =
2011 cast<cir::GlobalViewAttr>(cgm.getAddrOfRTTIDescriptor(loc, ty));
2012 // `getAddrOfRTTIDescriptor` lies to us and always gives us a uint8ptr as its
2013 // type, however we need the value of the actual global to call the
2014 // get-global-op, so look it up here.
2015 auto typeInfoGlobal =
2016 cast<cir::GlobalOp>(cgm.getGlobalValue(typeInfo.getSymbol().getValue()));
2017 auto getTypeInfo = cir::GetGlobalOp::create(
2018 builder, loc, builder.getPointerTo(typeInfoGlobal.getSymType()),
2019 typeInfoGlobal.getSymName());
2020 // The ABI is just generating these sometimes as ptr to u8, but they are
2021 // simply a representation of the type_info. So we have to cast this, if
2022 // necessary (createBitcast is a noop if the types match).
2023 return builder.createBitcast(getTypeInfo, resultType);
2024}
static bool emit(llvm::SmallVectorImpl< std::byte > &Code, const T &Val)
Helper to write bytecode and bail out if 32-bit offsets become invalid.
static CXXRecordDecl * getCXXRecord(const Expr *E)
static void emitNewInitializer(CIRGenFunction &cgf, const CXXNewExpr *e, QualType elementType, mlir::Type elementTy, Address newPtr, mlir::Value numElements, mlir::Value allocSizeWithoutCookie)
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 Address emitCXXTypeidOperand(CIRGenFunction &cgf, const Expr *e, bool hasNullCheck)
static mlir::Value emitCXXNewAllocSize(CIRGenFunction &cgf, const CXXNewExpr *e, unsigned minElements, mlir::Value &numElements, mlir::Value &sizeWithoutCookie)
static void emitDestroyingObjectDelete(CIRGenFunction &cgf, const CXXDeleteExpr *de, Address ptr, QualType elementType)
Emit the code for deleting a single object via a destroying operator delete.
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)
cir::ConstantOp getAlignment(mlir::Location loc, mlir::Type t, clang::CharUnits alignment)
llvm::Align getABITypeAlign(mlir::Type ty) const
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 ...
Definition ASTContext.h:245
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
Definition ASTContext.h:856
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.
static uint64_t getConstantArrayElementCount(const ConstantArrayType *CA)
Return number of (potentially nested) constant array elements.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
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.
Definition TypeBase.h:3820
A builtin binary operation expression such as "x + y" or "x <= y".
Definition Expr.h:4107
Expr * getLHS() const
Definition Expr.h:4157
Expr * getRHS() const
Definition Expr.h:4159
Opcode getOpcode() const
Definition Expr.h:4152
Address withPointer(mlir::Value newPtr) const
Return address with different pointer, but same element type and alignment.
Definition Address.h:83
mlir::Value getPointer() const
Definition Address.h:98
mlir::Type getElementType() const
Definition Address.h:125
static Address invalid()
Definition Address.h:76
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
Definition Address.h:138
Address withAlignment(clang::CharUnits newAlignment) const
Return address with different alignment, but same pointer and element type.
Definition Address.h:89
mlir::Type getType() const
Definition Address.h:117
bool isValid() const
Definition Address.h:77
mlir::Value emitRawPointer() const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
Definition Address.h:112
An aggregate value slot.
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)
cir::IntType getSIntNTy(int n)
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, bool isNontemporal=false, mlir::IntegerAttr align={}, cir::SyncScopeKindAttr scope={}, cir::MemOrderAttr order={})
cir::LoadOp createAlignedLoad(mlir::Location loc, mlir::Type ty, mlir::Value ptr, llvm::MaybeAlign align)
bool isNullValue(mlir::Attribute attr) const
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 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())
Definition CIRGenCall.h:92
static CIRGenCallee forVirtual(const clang::CallExpr *ce, clang::GlobalDecl md, Address addr, cir::FuncType fTy)
Definition CIRGenCall.h:156
An abstract representation of regular/ObjC call/message targets.
An object to manage conditionally-evaluated expressions.
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...
void initFullExprCleanup()
Set up the last cleanup that was pushed as a conditional full-expression cleanup.
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)
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.
void pushIrregularPartialArrayCleanup(mlir::Value arrayBegin, Address arrayEndPointer, QualType elementType, CharUnits elementAlign, Destroyer *destroyer)
Push an EH cleanup to destroy already-constructed elements of the given array.
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
void emitCallArgs(CallArgList &args, PrototypeWrapper prototype, llvm::iterator_range< clang::CallExpr::const_arg_iterator > argRange, AbstractCallee callee=AbstractCallee(), unsigned paramsToSkip=0, EvaluationOrder order=EvaluationOrder::Default)
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)
void emitScalarInit(const clang::Expr *init, LValue lvalue, bool capturedByInit=false)
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.
static int64_t getZExtIntValueFromConstOp(mlir::Value val)
Get zero-extended integer from a mlir::Value that is an int constant or a constant op.
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 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()
Destroyer * getDestroyer(clang::QualType::DestructionKind kind)
void popCleanupBlock(bool forDeactivation=false)
Pop a cleanup block from the stack.
std::optional< SourceRange > currSrcLoc
Use to track source locations across nested visitor traversals.
void emitComplexExprIntoLValue(const Expr *e, LValue dest, bool isInit)
RValue emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, const CallArgList &args, cir::CIRCallOpInterface *callOp, bool isMustTail, SourceRange clangLoc)
LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)
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.
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.
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...
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.
const cir::CIRDataLayout & getDataLayout() const
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 clang::CodeGenOptions & getCodeGenOpts() 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.
Definition CIRGenCall.h:250
void add(RValue rvalue, clang::QualType type)
Definition CIRGenCall.h:241
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.
Definition CIRGenValue.h:33
static RValue get(mlir::Value v)
Definition CIRGenValue.h:83
static RValue getAggregate(Address addr, bool isVolatile=false)
Convert an Address to an RValue.
mlir::Value getValue() const
Return the value of this scalar value.
Definition CIRGenValue.h:57
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...
Definition CIRGenCall.h:262
Represents a call to a CUDA kernel function.
Definition ExprCXX.h:239
Represents a call to a C++ constructor.
Definition ExprCXX.h:1553
bool isElidable() const
Whether this construction is elidable.
Definition ExprCXX.h:1622
Expr * getArg(unsigned Arg)
Return the specified argument.
Definition ExprCXX.h:1696
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
Definition ExprCXX.h:1655
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition ExprCXX.h:1616
CXXConstructionKind getConstructionKind() const
Determine whether this constructor is actually constructing a base class (rather than a complete obje...
Definition ExprCXX.h:1664
Represents a C++ constructor within a class.
Definition DeclCXX.h:2645
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Definition DeclCXX.cpp:3049
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition ExprCXX.h:2631
FunctionDecl * getOperatorDelete() const
Definition ExprCXX.h:2670
bool isArrayForm() const
Definition ExprCXX.h:2657
QualType getDestroyedType() const
Retrieve the type being destroyed.
Definition ExprCXX.cpp:345
Represents a C++ destructor within a class.
Definition DeclCXX.h:2915
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
Definition ExprCXX.h:486
bool isAlwaysNull() const
isAlwaysNull - Return whether the result of the dynamic_cast is proven to always be null.
Definition ExprCXX.cpp:870
Represents a call to a member function that may be written either with member call syntax (e....
Definition ExprCXX.h:184
SourceLocation getExprLoc() const LLVM_READONLY
Definition ExprCXX.h:225
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2153
bool isVirtual() const
Definition DeclCXX.h:2208
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition DeclCXX.h:2296
bool isInstance() const
Definition DeclCXX.h:2180
CXXMethodDecl * getDevirtualizedMethod(const Expr *Base, bool IsAppleKext)
If it's possible to devirtualize a call to this method, return the called function.
Definition DeclCXX.cpp:2524
CXXMethodDecl * getCorrespondingMethodInClass(const CXXRecordDecl *RD, bool MayBeBase=false)
Find the method in RD that corresponds to this one.
Definition DeclCXX.cpp:2470
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition ExprCXX.h:2360
bool isArray() const
Definition ExprCXX.h:2469
llvm::iterator_range< arg_iterator > placement_arguments()
Definition ExprCXX.h:2577
QualType getAllocatedType() const
Definition ExprCXX.h:2439
unsigned getNumImplicitArgs() const
Definition ExprCXX.h:2516
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
Definition ExprCXX.h:2474
ImplicitAllocationParameters implicitAllocationParameters() const
Provides the full set of information about expected implicit parameters in this call.
Definition ExprCXX.h:2567
bool hasInitializer() const
Whether this new-expression has any initializer at all.
Definition ExprCXX.h:2529
bool shouldNullCheckAllocation() const
True if the allocation result needs to be null-checked.
Definition ExprCXX.cpp:333
bool passAlignment() const
Indicates whether the required alignment should be implicitly passed to the allocation function.
Definition ExprCXX.h:2556
FunctionDecl * getOperatorDelete() const
Definition ExprCXX.h:2466
unsigned getNumPlacementArgs() const
Definition ExprCXX.h:2499
SourceRange getSourceRange() const
Definition ExprCXX.h:2615
FunctionDecl * getOperatorNew() const
Definition ExprCXX.h:2464
Expr * getInitializer()
The initializer of this new-expression.
Definition ExprCXX.h:2538
A call to an overloaded operator written using operator syntax.
Definition ExprCXX.h:86
Represents a list-initialization with parenthesis.
Definition ExprCXX.h:5195
MutableArrayRef< Expr * > getInitExprs()
Definition ExprCXX.h:5235
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
Definition ExprCXX.h:2750
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
Definition DeclCXX.h:1196
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
Definition DeclCXX.cpp:2129
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Definition ExprCXX.h:853
bool isTypeOperand() const
Definition ExprCXX.h:889
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Definition ExprCXX.cpp:168
Expr * getExprOperand() const
Definition ExprCXX.h:900
SourceRange getSourceRange() const LLVM_READONLY
Definition ExprCXX.h:907
bool isMostDerived(const ASTContext &Context) const
Best-effort check if the expression operand refers to a most derived object.
Definition ExprCXX.cpp:151
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr....
Definition ExprCXX.cpp:136
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...
Definition ExprCXX.cpp:207
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:3012
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition Expr.h:3216
arg_iterator arg_begin()
Definition Expr.h:3269
arg_iterator arg_end()
Definition Expr.h:3272
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition Expr.h:3195
Expr * getCallee()
Definition Expr.h:3159
arg_range arguments()
Definition Expr.h:3264
Expr * getSubExpr()
Definition Expr.h:3795
This is an opaque type for sizes expressed in character units.
Definition CharUnits.h:38
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
Definition CharUnits.h:177
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
Definition CharUnits.h:155
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
Definition CharUnits.h:184
bool isOne() const
Test whether the quantity equals one.
Definition CharUnits.h:104
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
Definition CharUnits.h:58
static CharUnits Zero()
Construct a CharUnits quantity of zero.
Definition CharUnits.h:52
Represents the canonical version of C arrays with a specified constant size.
Definition TypeBase.h:3858
The results of name lookup within a DeclContext.
Definition DeclBase.h:1400
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.
Definition DeclBase.h:436
DeclarationName getCXXOperatorName(OverloadedOperatorKind Op)
Get the name of the overloadable C++ operator corresponding to Op.
The name of a declaration.
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
Definition Expr.h:4024
This represents one expression.
Definition Expr.h:114
const CXXRecordDecl * getBestDynamicClassType() const
For an expression of class type or pointer to class type, return the most derived class decl the expr...
Definition Expr.cpp:70
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition Expr.cpp:3129
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3125
Expr * IgnoreParenBaseCasts() LLVM_READONLY
Skip past any parentheses and derived-to-base casts until reaching a fixed point.
Definition Expr.cpp:3151
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
Definition Expr.cpp:3292
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition Expr.cpp:283
QualType getType() const
Definition Expr.h:146
Represents a member of a struct/union/class.
Definition Decl.h:3341
Represents a function declaration or definition.
Definition Decl.h:2082
bool isDestroyingOperatorDelete() const
Determine whether this is a destroying operator delete.
Definition Decl.cpp:3624
QualType getReturnType() const
Definition Decl.h:3022
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition Decl.h:2546
bool isReplaceableGlobalAllocationFunction(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions:
Definition Decl.h:2765
UsualDeleteParams getUsualDeleteParams() const
Definition Decl.cpp:3640
bool isReservedGlobalPlacementOperator() const
Determines whether this operator new or delete is one of the reserved global placement operators: voi...
Definition Decl.cpp:3476
bool isDefaulted() const
Whether this function is defaulted.
Definition Decl.h:2554
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4645
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5548
unsigned getNumParams() const
Definition TypeBase.h:5826
QualType getParamType(unsigned i) const
Definition TypeBase.h:5828
CanThrowResult canThrow() const
Determine whether this function type has a non-throwing exception specification.
Definition Type.cpp:4113
GlobalDecl - represents a global declaration.
Definition GlobalDecl.h:60
const Decl * getDecl() const
Definition GlobalDecl.h:115
Represents an implicitly-generated value initialization of an object of a given type.
Definition Expr.h:6143
Describes an C or C++ initializer list.
Definition Expr.h:5377
bool isStringLiteralInit() const
Is this an initializer for an array of characters, initialized by a string literal or an @encode?
Definition Expr.cpp:2487
unsigned getNumInits() const
Definition Expr.h:5410
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
Definition Expr.h:5491
const Expr * getInit(unsigned Init) const
Definition Expr.h:5443
ArrayRef< Expr * > inits() const
Definition Expr.h:5441
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition TypeBase.h:3751
QualType getPointeeType() const
Definition TypeBase.h:3769
This represents a decl that may have a name.
Definition Decl.h:276
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:342
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
ObjCEncodeExpr, used for @encode in Objective-C.
Definition ExprObjC.h:440
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition TypeBase.h:3403
A (possibly-)qualified type.
Definition TypeBase.h:938
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1005
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition TypeBase.h:8618
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
Definition TypeBase.h:1454
QualType getCanonicalType() const
Definition TypeBase.h:8630
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
Definition TypeBase.h:1561
bool isPODType(const ASTContext &Context) const
Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
Definition Type.cpp:2914
bool hasStrongOrWeakObjCLifetime() const
Definition TypeBase.h:1462
Represents a struct/union/class.
Definition Decl.h:4506
field_range fields() const
Definition Decl.h:4709
RecordDecl * getDefinitionOrSelf() const
Definition Decl.h:4694
Base for LValueReferenceType and RValueReferenceType.
Definition TypeBase.h:3678
A trivial tuple used to represent a source range.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:343
StringLiteral - This represents a string literal expression, e.g.
Definition Expr.h:1844
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:5001
bool isUnion() const
Definition Decl.h:4109
Exposes information about the current target.
Definition TargetInfo.h:228
unsigned getNewAlign() const
Return the largest alignment for which a suitably-sized allocation with 'operator new(size_t)' is gua...
Definition TargetInfo.h:762
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:3728
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition Type.h:26
bool isConstantArrayType() const
Definition TypeBase.h:8918
bool isVoidPointerType() const
Definition Type.cpp:845
bool isPointerType() const
Definition TypeBase.h:8815
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9498
bool isReferenceType() const
Definition TypeBase.h:8839
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
Definition Type.cpp:2080
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:885
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition TypeBase.h:9484
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:3002
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9431
bool isRecordType() const
Definition TypeBase.h:8942
QualType getType() const
Definition Decl.h:725
@ 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 AstTypeMatcher< TagType > tagType
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.
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
Definition PrimType.h:218
Top level wrappers for InstallAPI frontend operations.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
CXXCtorType
C++ constructor types.
Definition ABI.h:24
@ Ctor_Base
Base object ctor.
Definition ABI.h:26
@ Ctor_Complete
Complete object ctor.
Definition ABI.h:25
bool isa(CodeGen::Address addr)
Definition Address.h:330
AlignedAllocationMode alignedAllocationModeFromBool(bool IsAligned)
Definition ExprCXX.h:2274
bool isAlignedAllocation(AlignedAllocationMode Mode)
Definition ExprCXX.h:2270
AlignedAllocationMode
Definition ExprCXX.h:2268
@ Dtor_Complete
Complete object dtor.
Definition ABI.h:36
bool isTypeAwareAllocation(TypeAwareAllocationMode Mode)
Definition ExprCXX.h:2258
TypeAwareAllocationMode
Definition ExprCXX.h:2256
U cast(CodeGen::Address addr)
Definition Address.h:327
__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)
static bool objCLifetime()
static bool addressSpace()
static bool devirtualizeDestructor()
static bool aggValueSlotGC()
static bool deleteArray()
static bool emitTypeCheck()
static bool typeAwareAllocation()
static bool emitNullCheckForDeleteCalls()
static bool generateDebugInfo()
Scope that deactivates all enclosed deferred cleanups on exit.
clang::CharUnits getPointerAlign() const
clang::CharUnits getSizeAlign() const
The parameters to pass to a usual operator delete.
Definition ExprCXX.h:2349
TypeAwareAllocationMode TypeAwareDelete
Definition ExprCXX.h:2350
AlignedAllocationMode Alignment
Definition ExprCXX.h:2353