clang 23.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());
122 return emitCall(cgm.getTypes().arrangeCXXMethodCall(argsList, fpt, required,
123 /*PrefixSize=*/0),
124 callee, returnValue, argsList, nullptr, loc);
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);
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 mlir::Location loc = ce ? getLoc(ce->getExprLoc()) : *currSrcLoc;
326 return emitCall(fnInfo, callee, returnValue, args, nullptr, 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 and size overflow.
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 const llvm::APInt &count =
519 mlir::cast<cir::IntAttr>(constNumElements).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(!count.isNegative() && "Expected non-negative array size");
533 assert(numElementsWidth <= sizeWidth &&
534 "Expected a size_t array size constant");
535
536 // Okay, compute a count at the right width.
537 llvm::APInt adjustedCount = count.zextOrTrunc(sizeWidth);
538
539 // Scale numElements by that. This might overflow, but we don't
540 // care because it only overflows if allocationSize does too, and
541 // if that overflows then we shouldn't use this.
542 // This emits a constant that may not be used, but we can't tell here
543 // whether it will be needed or not.
544 numElements =
545 cgf.getBuilder().getConstInt(loc, adjustedCount * arraySizeMultiplier);
546
547 // Compute the size before cookie, and track whether it overflowed.
548 bool overflow;
549 llvm::APInt allocationSize =
550 adjustedCount.umul_ov(typeSizeMultiplier, overflow);
551
552 // Sema prevents us from hitting this case
553 assert(!overflow && "Overflow in array allocation size");
554
555 // Add in the cookie, and check whether it's overflowed.
556 if (cookieSize != 0) {
557 // Save the current size without a cookie. This shouldn't be
558 // used if there was overflow
559 sizeWithoutCookie = cgf.getBuilder().getConstInt(
560 loc, allocationSize.zextOrTrunc(sizeWidth));
561
562 allocationSize = allocationSize.uadd_ov(cookieSize, overflow);
563 hasAnyOverflow |= overflow;
564 }
565
566 // On overflow, produce a -1 so operator new will fail
567 if (hasAnyOverflow) {
568 size =
569 cgf.getBuilder().getConstInt(loc, llvm::APInt::getAllOnes(sizeWidth));
570 } else {
571 size = cgf.getBuilder().getConstInt(loc, allocationSize);
572 }
573 } else {
574 // Create a value for the variable number of elements
575 numElements = cgf.emitScalarExpr(*e->getArraySize());
576 auto numElementsType = mlir::cast<cir::IntType>(numElements.getType());
577 unsigned numElementsWidth = numElementsType.getWidth();
578
579 // The number of elements can have an arbitrary integer type;
580 // essentially, we need to multiply it by a constant factor, add a
581 // cookie size, and verify that the result is representable as a
582 // size_t. That's just a gloss, though, and it's wrong in one
583 // important way: if the count is negative, it's an error even if
584 // the cookie size would bring the total size >= 0.
585 bool isSigned =
586 (*e->getArraySize())->getType()->isSignedIntegerOrEnumerationType();
587
588 // There are up to five conditions we need to test for:
589 // 1) if isSigned, we need to check whether numElements is negative;
590 // 2) if numElementsWidth > sizeWidth, we need to check whether
591 // numElements is larger than something representable in size_t;
592 // 3) if minElements > 0, we need to check whether numElements is smaller
593 // than that.
594 // 4) we need to compute
595 // sizeWithoutCookie := numElements * typeSizeMultiplier
596 // and check whether it overflows; and
597 // 5) if we need a cookie, we need to compute
598 // size := sizeWithoutCookie + cookieSize
599 // and check whether it overflows.
600
601 mlir::Value hasOverflow;
602
603 // If numElementsWidth > sizeWidth, then one way or another, we're
604 // going to have to do a comparison for (2), and this happens to
605 // take care of (1), too.
606 if (numElementsWidth > sizeWidth) {
607 llvm::APInt threshold =
608 llvm::APInt::getOneBitSet(numElementsWidth, sizeWidth);
609
610 // Use an unsigned comparison regardless of the sign of numElements.
611 mlir::Value unsignedNumElements = numElements;
612 if (isSigned)
613 unsignedNumElements = cgf.getBuilder().createIntCast(
614 numElements, cgf.getBuilder().getUIntNTy(numElementsWidth));
615
616 mlir::Value thresholdV =
617 cgf.getBuilder().getConstInt(loc, threshold, /*isUnsigned=*/true);
618 hasOverflow = cgf.getBuilder().createCompare(
619 loc, cir::CmpOpKind::ge, unsignedNumElements, thresholdV);
620 numElements = cgf.getBuilder().createIntCast(
621 unsignedNumElements, mlir::cast<cir::IntType>(cgf.sizeTy));
622
623 // Otherwise, if we're signed, we want to sext up to size_t.
624 } else if (isSigned) {
625 if (numElementsWidth < sizeWidth)
626 numElements = cgf.getBuilder().createIntCast(
627 numElements, cgf.getBuilder().getSIntNTy(sizeWidth));
628
629 // If there's a non-1 type size multiplier, then we can do the
630 // signedness check at the same time as we do the multiply
631 // because a negative number times anything will cause an
632 // unsigned overflow. Otherwise, we have to do it here. But at
633 // least in this case, we can subsume the >= minElements check.
634 if (typeSizeMultiplier == 1)
635 hasOverflow = cgf.getBuilder().createCompare(
636 loc, cir::CmpOpKind::lt, numElements,
637 cgf.getBuilder().getConstInt(loc, numElements.getType(),
638 minElements));
639
640 numElements = cgf.getBuilder().createIntCast(
641 numElements, mlir::cast<cir::IntType>(cgf.sizeTy));
642
643 // Otherwise, zext up to size_t if necessary.
644 } else if (numElementsWidth < sizeWidth) {
645 numElements = cgf.getBuilder().createIntCast(
646 numElements, mlir::cast<cir::IntType>(cgf.sizeTy));
647 }
648
649 assert(numElements.getType() == cgf.sizeTy);
650
651 if (minElements) {
652 // Don't allow allocation of fewer elements than we have initializers.
653 if (!hasOverflow) {
654 mlir::Value minElementsV = cgf.getBuilder().getConstInt(
655 loc, llvm::APInt(sizeWidth, minElements));
656 hasOverflow = cgf.getBuilder().createCompare(loc, cir::CmpOpKind::lt,
657 numElements, minElementsV);
658 } else if (numElementsWidth > sizeWidth) {
659 // The other existing overflow subsumes this check.
660 // We do an unsigned comparison, since any signed value < -1 is
661 // taken care of either above or below.
662 mlir::Value minElementsV = cgf.getBuilder().getConstInt(
663 loc, llvm::APInt(sizeWidth, minElements));
664 hasOverflow = cgf.getBuilder().createOr(
665 loc, hasOverflow,
666 cgf.getBuilder().createCompare(loc, cir::CmpOpKind::lt, numElements,
667 minElementsV));
668 }
669 }
670
671 size = numElements;
672
673 // Multiply by the type size if necessary. This multiplier
674 // includes all the factors for nested arrays.
675 //
676 // This step also causes numElements to be scaled up by the
677 // nested-array factor if necessary. Overflow on this computation
678 // can be ignored because the result shouldn't be used if
679 // allocation fails.
680 if (typeSizeMultiplier != 1) {
681 mlir::Value tsmV = cgf.getBuilder().getConstInt(loc, typeSizeMultiplier);
682 auto mulOp = cir::MulOverflowOp::create(
683 cgf.getBuilder(), loc, mlir::cast<cir::IntType>(cgf.sizeTy), size,
684 tsmV);
685
686 if (hasOverflow)
687 hasOverflow =
688 cgf.getBuilder().createOr(loc, hasOverflow, mulOp.getOverflow());
689 else
690 hasOverflow = mulOp.getOverflow();
691
692 size = mulOp.getResult();
693
694 // Also scale up numElements by the array size multiplier.
695 if (arraySizeMultiplier != 1) {
696 // If the base element type size is 1, then we can re-use the
697 // multiply we just did.
698 if (typeSize.isOne()) {
699 assert(arraySizeMultiplier == typeSizeMultiplier);
700 numElements = size;
701
702 // Otherwise we need a separate multiply.
703 } else {
704 mlir::Value asmV =
705 cgf.getBuilder().getConstInt(loc, arraySizeMultiplier);
706 numElements = cgf.getBuilder().createMul(loc, numElements, asmV);
707 }
708 }
709 } else {
710 // numElements doesn't need to be scaled.
711 assert(arraySizeMultiplier == 1);
712 }
713
714 // Add in the cookie size if necessary.
715 if (cookieSize != 0) {
716 sizeWithoutCookie = size;
717 mlir::Value cookieSizeV = cgf.getBuilder().getConstInt(loc, cookieSize);
718 auto addOp = cir::AddOverflowOp::create(
719 cgf.getBuilder(), loc, mlir::cast<cir::IntType>(cgf.sizeTy), size,
720 cookieSizeV);
721
722 if (hasOverflow)
723 hasOverflow =
724 cgf.getBuilder().createOr(loc, hasOverflow, addOp.getOverflow());
725 else
726 hasOverflow = addOp.getOverflow();
727
728 size = addOp.getResult();
729 }
730
731 // If we had any possibility of dynamic overflow, make a select to
732 // overwrite 'size' with an all-ones value, which should cause
733 // operator new to throw.
734 if (hasOverflow) {
735 mlir::Value allOnes =
736 cgf.getBuilder().getConstInt(loc, llvm::APInt::getAllOnes(sizeWidth));
737 size = cgf.getBuilder().createSelect(loc, hasOverflow, allOnes, size);
738 }
739 }
740
741 if (cookieSize == 0)
742 sizeWithoutCookie = size;
743 else
744 assert(sizeWithoutCookie && "didn't set sizeWithoutCookie?");
745
746 return size;
747}
748
749/// Emit a call to an operator new or operator delete function, as implicitly
750/// created by new-expressions and delete-expressions.
752 const FunctionDecl *calleeDecl,
753 const FunctionProtoType *calleeType,
754 const CallArgList &args) {
755 cir::CIRCallOpInterface callOrTryCall;
756 cir::FuncOp calleePtr = cgf.cgm.getAddrOfFunction(calleeDecl);
757 CIRGenCallee callee =
758 CIRGenCallee::forDirect(calleePtr, GlobalDecl(calleeDecl));
759 RValue rv =
760 cgf.emitCall(cgf.cgm.getTypes().arrangeFreeFunctionCall(args, calleeType),
761 callee, ReturnValueSlot(), args, &callOrTryCall);
762
763 /// C++1y [expr.new]p10:
764 /// [In a new-expression,] an implementation is allowed to omit a call
765 /// to a replaceable global allocation function.
766 ///
767 /// We model such elidable calls with the 'builtin' attribute.
768 if (calleeDecl->isReplaceableGlobalAllocationFunction() && calleePtr &&
769 calleePtr->hasAttr(cir::CIRDialect::getNoBuiltinAttrName())) {
770 callOrTryCall->setAttr(cir::CIRDialect::getBuiltinAttrName(),
771 mlir::UnitAttr::get(callOrTryCall->getContext()));
772 }
773
774 return rv;
775}
776
778 const CallExpr *callExpr,
780 CallArgList args;
781 emitCallArgs(args, type, callExpr->arguments());
782 // Find the allocation or deallocation function that we're calling.
783 ASTContext &astContext = getContext();
784 assert(op == OO_New || op == OO_Delete);
786
787 clang::DeclContextLookupResult lookupResult =
788 astContext.getTranslationUnitDecl()->lookup(name);
789 for (const NamedDecl *decl : lookupResult) {
790 if (const auto *funcDecl = dyn_cast<FunctionDecl>(decl)) {
791 if (astContext.hasSameType(funcDecl->getType().getTypePtr(), type)) {
792 if (sanOpts.has(SanitizerKind::AllocToken)) {
793 // TODO: Set !alloc_token metadata.
795 cgm.errorNYI("Alloc token sanitizer not yet supported!");
796 }
797
798 // Emit the call to operator new/delete.
799 return emitNewDeleteCall(*this, funcDecl, type, args);
800 }
801 }
802 }
803
804 llvm_unreachable("predeclared global operator new/delete is missing");
805}
806
807namespace {
808template <typename Traits> struct PlacementArg {
809 typename Traits::RValueTy argValue;
810 QualType argType;
811};
812
813/// A cleanup to call the given 'operator delete' function upon abnormal
814/// exit from a new expression. Templated on a traits type that deals with
815/// ensuring that the arguments dominate the cleanup if necessary.
816template <typename Traits>
817class CallDeleteDuringNew final
818 : public EHScopeStack::Cleanup,
819 private llvm::TrailingObjects<CallDeleteDuringNew<Traits>,
820 PlacementArg<Traits>> {
821 using TrailingObj =
822 llvm::TrailingObjects<CallDeleteDuringNew<Traits>, PlacementArg<Traits>>;
823 friend TrailingObj;
824 using TrailingObj::getTrailingObjects;
825
826 /// Type used to hold llvm::Value*s.
827 typedef typename Traits::ValueTy ValueTy;
828 /// Type used to hold RValues.
829 typedef typename Traits::RValueTy RValueTy;
830
831 unsigned numPlacementArgs : 30;
832 LLVM_PREFERRED_TYPE(AlignedAllocationMode)
833 unsigned passAlignmentToPlacementDelete : 1;
834 const FunctionDecl *operatorDelete;
835 ValueTy ptr;
836 ValueTy allocSize;
837 CharUnits allocAlign;
838
839 PlacementArg<Traits> *getPlacementArgs() { return getTrailingObjects(); }
840
841public:
842 void setPlacementArg(unsigned i, RValueTy argValue, QualType argType) {
843 assert(i < numPlacementArgs && "index out of range");
844 getPlacementArgs()[i] = {argValue, argType};
845 }
846
847 static size_t getExtraSize(size_t numPlacementArgs) {
848 return TrailingObj::template additionalSizeToAlloc<PlacementArg<Traits>>(
849 numPlacementArgs);
850 }
851
852 CallDeleteDuringNew(size_t numPlacementArgs,
853 const FunctionDecl *operatorDelete, ValueTy ptr,
854 ValueTy allocSize,
855 const ImplicitAllocationParameters &iap,
856 CharUnits allocAlign)
857 : numPlacementArgs(numPlacementArgs),
858 passAlignmentToPlacementDelete(isAlignedAllocation(iap.PassAlignment)),
859 operatorDelete(operatorDelete), ptr(ptr), allocSize(allocSize),
860 allocAlign(allocAlign) {}
861
862 void emit(CIRGenFunction &cgf, Flags flags) override {
863 const auto *fpt = operatorDelete->getType()->castAs<FunctionProtoType>();
864 CallArgList deleteArgs;
865
866 unsigned firstNonTypeArg = 0;
867 TypeAwareAllocationMode typeAwareDeallocation = TypeAwareAllocationMode::No;
869
870 // The first argument after type-identity parameter (if any) is always
871 // a void* (or C* for a destroying operator delete for class type C).
872 deleteArgs.add(Traits::get(cgf, ptr), fpt->getParamType(firstNonTypeArg));
873
874 // Figure out what other parameters we should be implicitly passing.
875 UsualDeleteParams params;
876 if (numPlacementArgs) {
877 // A placement deallocation function is implicitly passed an alignment
878 // if the placement allocation function was, but is never passed a size.
879 params.Alignment =
880 alignedAllocationModeFromBool(passAlignmentToPlacementDelete);
881 params.TypeAwareDelete = typeAwareDeallocation;
883 } else {
884 // For a non-placement new-expression, 'operator delete' can take a
885 // size and/or an alignment if it has the right parameters.
886 params = operatorDelete->getUsualDeleteParams();
887 }
888
889 assert(!params.DestroyingDelete &&
890 "should not call destroying delete in a new-expression");
891
892 // The second argument can be a std::size_t (for non-placement delete).
893 if (params.Size)
894 deleteArgs.add(Traits::get(cgf, allocSize),
895 cgf.getContext().getSizeType());
896
897 // The next (second or third) argument can be a std::align_val_t, which
898 // is an enum whose underlying type is std::size_t.
899 // FIXME: Use the right type as the parameter type. Note that in a call
900 // to operator delete(size_t, ...), we may not have it available.
901 if (isAlignedAllocation(params.Alignment)) {
902 QualType sizeType = cgf.getContext().getSizeType();
903 cir::ConstantOp align = cgf.getBuilder().getAlignment(
904 *cgf.currSrcLoc, cgf.convertType(sizeType), allocAlign);
905 deleteArgs.add(RValue::get(align), sizeType);
906 }
907
908 // Pass the rest of the arguments, which must match exactly.
909 for (unsigned i = 0; i != numPlacementArgs; ++i) {
910 auto arg = getPlacementArgs()[i];
911 deleteArgs.add(Traits::get(cgf, arg.argValue), arg.argType);
912 }
913
914 // Call 'operator delete'.
915 emitNewDeleteCall(cgf, operatorDelete, fpt, deleteArgs);
916 }
917};
918} // namespace
919
920/// Enter a cleanup to call 'operator delete' if the initializer in a
921/// new-expression throws.
923 Address newPtr, mlir::Value allocSize,
924 CharUnits allocAlign,
925 const CallArgList &newArgs) {
926 unsigned numNonPlacementArgs = e->getNumImplicitArgs();
927
928 // If we're not inside a conditional branch, then the cleanup will
929 // dominate and we can do the easier (and more efficient) thing.
930 if (!cgf.isInConditionalBranch()) {
931 struct DirectCleanupTraits {
932 typedef mlir::Value ValueTy;
933 typedef RValue RValueTy;
934 static RValue get(CIRGenFunction &, ValueTy v) { return RValue::get(v); }
935 static RValue get(CIRGenFunction &, RValueTy v) { return v; }
936 };
937
938 typedef CallDeleteDuringNew<DirectCleanupTraits> DirectCleanup;
939
941 DirectCleanup *cleanup = cgf.ehStack.pushCleanupWithExtra<DirectCleanup>(
943 newPtr.getPointer(), allocSize, e->implicitAllocationParameters(),
944 allocAlign);
945 for (auto i : llvm::seq<unsigned>(0, e->getNumPlacementArgs())) {
946 const CallArg &arg = newArgs[i + numNonPlacementArgs];
947 cleanup->setPlacementArg(
948 i, arg.getRValue(cgf, cgf.getLoc(e->getSourceRange())), arg.ty);
949 }
950
951 return;
952 }
953
954 // Otherwise, we need to save all this stuff.
955 auto saveValue = [&](mlir::Value value) -> mlir::Value {
957 cgf.cgm.getDataLayout().getABITypeAlign(value.getType()));
958 Address alloca = cgf.createTempAlloca(value.getType(), align,
959 value.getLoc(), "cond-cleanup.save");
960 cgf.getBuilder().createStore(value.getLoc(), value, alloca);
961 return alloca.emitRawPointer();
962 };
963
964 mlir::Value savedNewPtr = saveValue(newPtr.getPointer());
965 mlir::Value savedAllocSize = saveValue(allocSize);
966
967 struct ConditionalCleanupTraits {
968 typedef mlir::Value ValueTy;
969 typedef mlir::Value RValueTy;
970 static RValue get(CIRGenFunction &cgf, ValueTy v) {
971 while (cir::CastOp castOp = v.getDefiningOp<cir::CastOp>()) {
972 if (castOp.getKind() != cir::CastKind::address_space &&
973 castOp.getKind() != cir::CastKind::bitcast)
974 break;
975 v = castOp.getSrc();
976 }
977 cir::AllocaOp alloca = v.getDefiningOp<cir::AllocaOp>();
979 alloca.getLoc(), alloca.getAllocaType(), alloca,
980 llvm::MaybeAlign(alloca.getAlignment())));
981 }
982 };
983 typedef CallDeleteDuringNew<ConditionalCleanupTraits> ConditionalCleanup;
984
986 ConditionalCleanup *cleanup =
987 cgf.ehStack.pushCleanupWithExtra<ConditionalCleanup>(
989 savedNewPtr, savedAllocSize, e->implicitAllocationParameters(),
990 allocAlign);
991 for (auto i : llvm::seq<unsigned>(0, e->getNumPlacementArgs())) {
992 const CallArg &arg = newArgs[i + numNonPlacementArgs];
993 cleanup->setPlacementArg(
994 i,
995 saveValue(
996 arg.getRValue(cgf, cgf.getLoc(e->getSourceRange())).getValue()),
997 arg.ty);
998 }
999
1000 cgf.initFullExprCleanup();
1001}
1002
1003static void storeAnyExprIntoOneUnit(CIRGenFunction &cgf, const Expr *init,
1004 QualType allocType, Address newPtr,
1005 AggValueSlot::Overlap_t mayOverlap) {
1006 // FIXME: Refactor with emitExprAsInit.
1007 switch (cgf.getEvaluationKind(allocType)) {
1008 case cir::TEK_Scalar:
1009 cgf.emitScalarInit(init, cgf.getLoc(init->getSourceRange()),
1010 cgf.makeAddrLValue(newPtr, allocType), false);
1011 return;
1012 case cir::TEK_Complex:
1013 cgf.emitComplexExprIntoLValue(init, cgf.makeAddrLValue(newPtr, allocType),
1014 /*isInit*/ true);
1015 return;
1016 case cir::TEK_Aggregate: {
1020 newPtr, allocType.getQualifiers(), AggValueSlot::IsDestructed,
1022 cgf.emitAggExpr(init, slot);
1023 return;
1024 }
1025 }
1026 llvm_unreachable("bad evaluation kind");
1027}
1028
1030 const CXXNewExpr *e, QualType elementType, mlir::Type elementTy,
1031 Address beginPtr, mlir::Value numElements,
1032 mlir::Value allocSizeWithoutCookie) {
1033 // If we have a type with trivial initialization and no initializer,
1034 // there's nothing to do.
1035 if (!e->hasInitializer())
1036 return;
1037
1038 Address curPtr = beginPtr;
1039
1040 unsigned initListElements = 0;
1041
1042 const Expr *init = e->getInitializer();
1043 Address endOfInit = Address::invalid();
1044 QualType::DestructionKind dtorKind = elementType.isDestructedType();
1045 CleanupDeactivationScope deactivation(*this);
1046
1047 // Attempt to perform zero-initialization using memset.
1048 auto tryMemsetInitialization = [&]() -> bool {
1049 mlir::Location loc = numElements.getLoc();
1050
1051 // FIXME: If the type is a pointer-to-data-member under the Itanium ABI,
1052 // we can initialize with a memset to -1.
1053 if (!cgm.getTypes().isZeroInitializable(elementType))
1054 return false;
1055
1056 // Optimization: since zero initialization will just set the memory
1057 // to all zeroes, generate a single memset to do it in one shot.
1058
1059 // Subtract out the size of any elements we've already initialized.
1060 auto remainingSize = allocSizeWithoutCookie;
1061 if (initListElements) {
1062 // We know this can't overflow; we check this when doing the allocation.
1063 unsigned initializedSize =
1064 getContext().getTypeSizeInChars(elementType).getQuantity() *
1065 initListElements;
1066 cir::ConstantOp initSizeOp =
1067 builder.getConstInt(loc, remainingSize.getType(), initializedSize);
1068 remainingSize = builder.createSub(loc, remainingSize, initSizeOp);
1069 }
1070
1071 // Create the memset.
1072 mlir::Value castOp =
1073 builder.createPtrBitcast(curPtr.getPointer(), cgm.voidTy);
1074 builder.createMemSet(loc, castOp, builder.getConstInt(loc, cgm.uInt8Ty, 0),
1075 remainingSize);
1076 return true;
1077 };
1078
1079 const InitListExpr *ile = dyn_cast<InitListExpr>(init);
1080 const CXXParenListInitExpr *cplie = nullptr;
1081 const StringLiteral *sl = nullptr;
1082 const ObjCEncodeExpr *ocee = nullptr;
1083 const Expr *ignoreParen = nullptr;
1084 if (!ile) {
1085 ignoreParen = init->IgnoreParenImpCasts();
1086 cplie = dyn_cast<CXXParenListInitExpr>(ignoreParen);
1087 sl = dyn_cast<StringLiteral>(ignoreParen);
1088 ocee = dyn_cast<ObjCEncodeExpr>(ignoreParen);
1089 }
1090 // If the initializer is an initializer list, first do the explicit elements.
1091 if (ile || cplie || sl || ocee) {
1092 // Initializing from a (braced) string literal is a special case; the init
1093 // list element does not initialize a (single) array element.
1094 if ((ile && ile->isStringLiteralInit()) || sl || ocee) {
1095 if (!ile)
1096 init = ignoreParen;
1097
1098 // Initialize the initial portion of length equal to that of the string
1099 // literal. The allocation must be for at least this much; we emitted a
1100 // check for that earlier. Since we intend to use a cir.copy here, we must
1101 // introduce a cast to the string-literal-size here, so that cir.copy does
1102 // the right thing.
1103
1104 const Expr *initExpr = ile ? ile->getInit(0) : init;
1105 mlir::Type initExprTy = convertType(initExpr->getType());
1106 Address coercedPtr = curPtr.withElementType(builder, initExprTy);
1107
1109 coercedPtr, elementType.getQualifiers(), AggValueSlot::IsDestructed,
1114 emitAggExpr(initExpr, slot);
1115
1116 // Move past these elements.
1117 initListElements =
1119 ->getZExtSize();
1120
1121 bool alreadyInitedAll = false;
1122 auto constElts = numElements.getDefiningOp<cir::ConstantOp>();
1123 if (constElts) {
1124 int64_t constVal = getZExtIntValueFromConstOp(numElements);
1125 alreadyInitedAll = (constVal == initListElements);
1126 }
1127
1128 // Init the rest with memset, unless we've already done everything.
1129 if (!alreadyInitedAll) {
1130 mlir::Location initLoc = cgm.getLoc(init->getSourceRange());
1131 mlir::Value initListElementsOp = builder.getUnsignedInt(
1132 initLoc, initListElements,
1133 getContext().getTypeSize(getContext().getSizeType()));
1134 curPtr = curPtr.withPointer(builder.createPtrStride(
1135 initLoc, curPtr.getPointer(), initListElementsOp));
1136
1137 bool ok = tryMemsetInitialization();
1138 (void)ok;
1139 assert(ok && "couldn't memset character type?");
1140 }
1141 return;
1142 }
1143
1144 ArrayRef<const Expr *> initExprs =
1145 ile ? ile->inits() : cplie->getInitExprs();
1146 initListElements = initExprs.size();
1147
1148 // If this is a multi-dimensional array new, we will initialize multiple
1149 // elements with each init list element.
1150 QualType allocType = e->getAllocatedType();
1151 if (const ConstantArrayType *cat = dyn_cast_or_null<ConstantArrayType>(
1152 allocType->getAsArrayTypeUnsafe())) {
1153 elementTy = convertTypeForMem(allocType);
1154 curPtr = curPtr.withElementType(builder, elementTy);
1155 initListElements *= getContext().getConstantArrayElementCount(cat);
1156 }
1157
1158 // Enter a partial-destruction Cleanup if necessary.
1159 CharUnits elementSize = getContext().getTypeSizeInChars(elementType);
1160 if (dtorKind) {
1161 mlir::Location loc = cgm.getLoc(init->getSourceRange());
1162 endOfInit = createTempAlloca(beginPtr.getType(), getPointerAlign(), loc,
1163 "arrayinit.endOfInit");
1165 beginPtr.getPointer(), endOfInit, elementType,
1166 beginPtr.getAlignment().alignmentOfArrayElement(elementSize),
1167 getDestroyer(dtorKind));
1168 }
1169
1170 CharUnits startAlign = curPtr.getAlignment();
1171 unsigned i = 0;
1172 for (const Expr *ie : initExprs) {
1173 mlir::Location loc = getLoc(ie->getExprLoc());
1174
1175 // Tell the cleanup that it needs to destroy up to this
1176 // element. TODO: some of these stores can be trivially
1177 // observed to be unnecessary.
1178 if (endOfInit.isValid())
1179 builder.createStore(loc, curPtr.getPointer(), endOfInit);
1180
1181 // FIXME: If the last initializer is an incomplete initializer list for
1182 // an array, and we have an array filler, we can fold together the two
1183 // initialization loops.
1184 storeAnyExprIntoOneUnit(*this, ie, ie->getType(), curPtr,
1186 mlir::Value castOp = builder.createPtrBitcast(
1187 curPtr.getPointer(), convertTypeForMem(allocType));
1188 mlir::Value offsetOp = builder.getSignedInt(loc, 1, /*width=*/32);
1189 mlir::Value dataPtr = builder.createPtrStride(loc, castOp, offsetOp);
1190 curPtr = Address(dataPtr, curPtr.getElementType(),
1191 startAlign.alignmentAtOffset((++i) * elementSize));
1192 }
1193
1194 // The remaining elements are filled with the array filler expression.
1195 init = ile ? ile->getArrayFiller() : cplie->getArrayFiller();
1196
1197 // Extract the initializer for the individual array elements by pulling
1198 // out the array filler from all the nested initializer lists. This avoids
1199 // generating a nested loop for the initialization.
1200 while (init && init->getType()->isConstantArrayType()) {
1201 auto *subIle = dyn_cast<InitListExpr>(init);
1202 if (!subIle)
1203 break;
1204 assert(subIle->getNumInits() == 0 && "explicit inits in array filler?");
1205 init = subIle->getArrayFiller();
1206 }
1207
1208 // Switch back to initializing one base element at a time.
1209 curPtr = curPtr.withElementType(builder, beginPtr.getElementType());
1210 }
1211
1212 // If all elements have already been initialized, skip any further
1213 // initialization.
1214 auto constOp = mlir::dyn_cast<cir::ConstantOp>(numElements.getDefiningOp());
1215 if (constOp) {
1216 auto constIntAttr = mlir::dyn_cast<cir::IntAttr>(constOp.getValue());
1217 // Just skip out if the constant count is zero.
1218 if (constIntAttr && constIntAttr.getUInt() <= initListElements)
1219 return;
1220 }
1221
1222 assert(init && "have trailing elements to initialize but no initializer");
1223
1224 // If this is a constructor call, try to optimize it out, and failing that
1225 // emit a single loop to initialize all remaining elements.
1226 if (const CXXConstructExpr *cce = dyn_cast<CXXConstructExpr>(init)) {
1227 CXXConstructorDecl *ctor = cce->getConstructor();
1228 if (ctor->isTrivial()) {
1229 // If new expression did not specify value-initialization, then there
1230 // is no initialization.
1231 if (!cce->requiresZeroInitialization())
1232 return;
1233
1234 cgm.errorNYI(cce->getSourceRange(),
1235 "emitNewArrayInitializer: trivial ctor zero-init");
1236 return;
1237 }
1238
1239 // Store the new Cleanup position for irregular Cleanups.
1240 //
1241 // FIXME: Share this cleanup with the constructor call emission rather than
1242 // having it create a cleanup of its own.
1243 if (endOfInit.isValid())
1244 builder.createStore(getLoc(e->getSourceRange()), curPtr.emitRawPointer(),
1245 endOfInit);
1246
1247 mlir::Type initType = convertType(cce->getType());
1248 // Emit a constructor call loop to initialize the remaining elements.
1249 if (initListElements) {
1250 // If the number of elements is a constant, we will have already gotten
1251 // the constant op above. Here we use it to get the number of remaining
1252 // elements as a new constant.
1253 if (constOp) {
1254 auto constIntAttr = mlir::cast<cir::IntAttr>(constOp.getValue());
1255 uint64_t numRemainingElements =
1256 constIntAttr.getUInt() - initListElements;
1257 numElements =
1258 builder.getConstInt(getLoc(e->getSourceRange()),
1259 numElements.getType(), numRemainingElements);
1260 // Currently, the AST gives us a pointer to the element type here
1261 // rather than an array. That's inconsistent with what it does
1262 // without an explicit initializer list, so we need to create an
1263 // array type here. That will decay back to a pointer when we lower
1264 // the cir.array.ctor op, but we need an array type for the initial
1265 // representation.
1266 if (!mlir::isa<cir::ArrayType>(initType))
1267 initType = cir::ArrayType::get(initType, numRemainingElements);
1268 } else {
1269 cgm.errorNYI(e->getSourceRange(),
1270 "emitNewArrayInitializer: numRemainingElements with "
1271 "non-constant count");
1272 return;
1273 }
1274 }
1275
1276 curPtr = curPtr.withElementType(builder, initType);
1277 emitCXXAggrConstructorCall(ctor, numElements, curPtr, cce,
1278 /*newPointerIsChecked=*/true,
1279 cce->requiresZeroInitialization(), endOfInit);
1280 if (getContext().getTargetInfo().emitVectorDeletingDtors(
1281 getContext().getLangOpts())) {
1282 cgm.errorNYI(e->getSourceRange(),
1283 "emitNewArrayInitializer: emitVectorDeletingDtors");
1284 }
1285 return;
1286 }
1287
1288 // If this is value-initialization, we can usually use memset.
1289 ImplicitValueInitExpr ivie(elementType);
1290 if (isa<ImplicitValueInitExpr>(init)) {
1291 if (tryMemsetInitialization())
1292 return;
1293 // Switch to an ImplicitValueInitExpr for the element type. This handles
1294 // only one case: multidimensional array new of pointers to members. In
1295 // all other cases, we already have an initializer for the array element.
1296 init = &ivie;
1297 }
1298
1299 // At this point we should have found an initializer for the individual
1300 // elements of the array.
1301 assert(getContext().hasSameUnqualifiedType(elementType, init->getType()) &&
1302 "got wrong type of element to initialize");
1303
1304 // If we have a struct whose every field is value-initialized, we can
1305 // usually use memset.
1306 if (auto *ile = dyn_cast<InitListExpr>(init)) {
1307
1308 // If we have an empty initializer list, we can usually use memset.
1309 if (ile->getNumInits() == 0 && tryMemsetInitialization())
1310 return;
1311
1312 if (const auto *rtype = ile->getType()->getAsCanonical<RecordType>()) {
1313 if (rtype->getDecl()->isStruct()) {
1314 const RecordDecl *rd = rtype->getDecl()->getDefinitionOrSelf();
1315 unsigned numElements = 0;
1316 if (auto *cxxrd = dyn_cast<CXXRecordDecl>(rd))
1317 numElements = cxxrd->getNumBases();
1318 for (FieldDecl *field : rd->fields())
1319 if (!field->isUnnamedBitField())
1320 ++numElements;
1321 // FIXME: Recurse into nested InitListExprs.
1322 if (ile->getNumInits() == numElements)
1323 for (unsigned i = 0, e = ile->getNumInits(); i != e; ++i)
1324 if (!isa<ImplicitValueInitExpr>(ile->getInit(i)))
1325 --numElements;
1326 if (ile->getNumInits() == numElements && tryMemsetInitialization())
1327 return;
1328 }
1329 }
1330 }
1331
1332 // The rest of this has to go through the rest of the initializer, generating
1333 // a loop with cleanups/destruction/etc. See the test
1334 // 'check_array_value_init'(currently disabled) in
1335 // CodeGenCXX/new-array-init.cpp when we get more of this implemented.
1336 cgm.errorNYI(init->getSourceRange(),
1337 "emitNewArrayInitializer: unsupported initializer");
1338 return;
1339}
1340
1342 QualType elementType, mlir::Type elementTy,
1343 Address newPtr, mlir::Value numElements,
1344 mlir::Value allocSizeWithoutCookie) {
1346 if (e->isArray()) {
1347 cgf.emitNewArrayInitializer(e, elementType, elementTy, newPtr, numElements,
1348 allocSizeWithoutCookie);
1349 } else if (const Expr *init = e->getInitializer()) {
1350 storeAnyExprIntoOneUnit(cgf, init, e->getAllocatedType(), newPtr,
1352 }
1353}
1354
1356 GlobalDecl dtor, const CIRGenCallee &callee, mlir::Value thisVal,
1357 QualType thisTy, mlir::Value implicitParam, QualType implicitParamTy,
1358 const CallExpr *ce) {
1359 const CXXMethodDecl *dtorDecl = cast<CXXMethodDecl>(dtor.getDecl());
1360
1361 assert(!thisTy.isNull());
1362 assert(thisTy->getAsCXXRecordDecl() == dtorDecl->getParent() &&
1363 "Pointer/Object mixup");
1364
1366
1367 CallArgList args;
1368 commonBuildCXXMemberOrOperatorCall(*this, dtorDecl, thisVal, implicitParam,
1369 implicitParamTy, ce, args, nullptr);
1370 assert((ce || dtor.getDecl()) && "expected source location provider");
1372 return emitCall(cgm.getTypes().arrangeCXXStructorDeclaration(dtor), callee,
1373 ReturnValueSlot(), args, nullptr,
1374 ce ? getLoc(ce->getExprLoc())
1375 : getLoc(dtor.getDecl()->getSourceRange()));
1376}
1377
1380 QualType destroyedType = expr->getDestroyedType();
1381 if (destroyedType.hasStrongOrWeakObjCLifetime()) {
1383 cgm.errorNYI(expr->getExprLoc(),
1384 "emitCXXPseudoDestructorExpr: Objective-C lifetime is NYI");
1385 } else {
1386 // C++ [expr.pseudo]p1:
1387 // The result shall only be used as the operand for the function call
1388 // operator (), and the result of such a call has type void. The only
1389 // effect is the evaluation of the postfix-expression before the dot or
1390 // arrow.
1391 emitIgnoredExpr(expr->getBase());
1392 }
1393
1394 return RValue::get(nullptr);
1395}
1396
1397namespace {
1398/// Calls the given 'operator delete' on a single object.
1399struct CallObjectDelete final : EHScopeStack::Cleanup {
1400 mlir::Value ptr;
1401 const FunctionDecl *operatorDelete;
1402 QualType elementType;
1403
1404 CallObjectDelete(mlir::Value ptr, const FunctionDecl *operatorDelete,
1405 QualType elementType)
1406 : ptr(ptr), operatorDelete(operatorDelete), elementType(elementType) {}
1407
1408 void emit(CIRGenFunction &cgf, Flags flags) override {
1409 cgf.emitDeleteCall(operatorDelete, ptr, elementType);
1410 }
1411};
1412} // namespace
1413
1414/// Emit the code for deleting a single object via a destroying operator
1415/// delete. If the element type has a non-virtual destructor, Ptr has already
1416/// been converted to the type of the parameter of 'operator delete'. Otherwise
1417/// Ptr points to an object of the static type.
1419 const CXXDeleteExpr *de, Address ptr,
1420 QualType elementType) {
1421 const CXXDestructorDecl *dtor =
1422 elementType->getAsCXXRecordDecl()->getDestructor();
1423 if (dtor && dtor->isVirtual()) {
1424 cgf.cgm.getCXXABI().emitVirtualObjectDelete(cgf, de, ptr, elementType,
1425 dtor);
1426 return;
1427 }
1428
1429 cgf.emitDeleteCall(de->getOperatorDelete(), ptr.getPointer(), elementType);
1430}
1431
1432/// Emit the code for deleting a single object.
1434 Address ptr, QualType elementType) {
1435 // C++11 [expr.delete]p3:
1436 // If the static type of the object to be deleted is different from its
1437 // dynamic type, the static type shall be a base class of the dynamic type
1438 // of the object to be deleted and the static type shall have a virtual
1439 // destructor or the behavior is undefined.
1441
1442 const FunctionDecl *operatorDelete = de->getOperatorDelete();
1443 assert(!operatorDelete->isDestroyingOperatorDelete());
1444
1445 // Find the destructor for the type, if applicable. If the
1446 // destructor is virtual, we'll just emit the vcall and return.
1447 const CXXDestructorDecl *dtor = nullptr;
1448 if (const auto *rd = elementType->getAsCXXRecordDecl()) {
1449 if (rd->hasDefinition() && !rd->hasTrivialDestructor()) {
1450 dtor = rd->getDestructor();
1451
1452 if (dtor->isVirtual()) {
1454 cgf.cgm.getCXXABI().emitVirtualObjectDelete(cgf, de, ptr, elementType,
1455 dtor);
1456 return;
1457 }
1458 }
1459 }
1460
1461 // Make sure that we call delete even if the dtor throws.
1462 // This doesn't have to a conditional cleanup because we're going
1463 // to pop it off in a second.
1464 cgf.ehStack.pushCleanup<CallObjectDelete>(
1465 NormalAndEHCleanup, ptr.getPointer(), operatorDelete, elementType);
1466
1467 if (dtor) {
1469 /*ForVirtualBase=*/false,
1470 /*Delegating=*/false, ptr, elementType);
1471 } else if (elementType.getObjCLifetime()) {
1473 cgf.cgm.errorNYI(de->getSourceRange(), "emitObjectDelete: ObjCLifetime");
1474 }
1475
1476 cgf.popCleanupBlock();
1477}
1478
1480 const Expr *arg = e->getArgument();
1482
1483 // Null check the pointer.
1484 //
1485 // We could avoid this null check if we can determine that the object
1486 // destruction is trivial and doesn't require an array cookie; we can
1487 // unconditionally perform the operator delete call in that case. For now, we
1488 // assume that deleted pointers are null rarely enough that it's better to
1489 // keep the branch. This might be worth revisiting for a -O0 code size win.
1491 cir::YieldOp thenYield;
1492 mlir::Value notNull = builder.createPtrIsNotNull(ptr.getPointer());
1493 cir::IfOp::create(builder, getLoc(e->getExprLoc()), notNull,
1494 /*withElseRegion=*/false,
1495 /*thenBuilder=*/
1496 [&](mlir::OpBuilder &b, mlir::Location loc) {
1497 thenYield = builder.createYield(loc);
1498 });
1499
1500 // Emit the rest of the CIR inside the if-op's then region, but restore the
1501 // insertion point to the point after the if when this function returns.
1502 mlir::OpBuilder::InsertionGuard guard(builder);
1503 builder.setInsertionPoint(thenYield);
1504
1505 QualType deleteTy = e->getDestroyedType();
1506
1507 // A destroying operator delete overrides the entire operation of the
1508 // delete expression.
1510 emitDestroyingObjectDelete(*this, e, ptr, deleteTy);
1511 return;
1512 }
1513
1514 // We might be deleting a pointer to array.
1515 deleteTy = getContext().getBaseElementType(deleteTy);
1516 ptr = ptr.withElementType(builder, convertTypeForMem(deleteTy));
1517
1518 if (e->isArrayForm() &&
1519 cgm.getASTContext().getTargetInfo().emitVectorDeletingDtors(
1520 cgm.getASTContext().getLangOpts())) {
1521 cgm.errorNYI(e->getSourceRange(),
1522 "emitCXXDeleteExpr: emitVectorDeletingDtors");
1523 }
1524
1525 if (e->isArrayForm()) {
1526 const FunctionDecl *operatorDelete = e->getOperatorDelete();
1527 cir::FuncOp operatorDeleteFn = cgm.getAddrOfFunction(operatorDelete);
1528 auto deleteFn =
1529 mlir::FlatSymbolRefAttr::get(operatorDeleteFn.getSymNameAttr());
1530 UsualDeleteParams udp = operatorDelete->getUsualDeleteParams();
1531 auto deleteParams = cir::UsualDeleteParamsAttr::get(
1532 builder.getContext(), udp.Size, isAlignedAllocation(udp.Alignment),
1534
1535 mlir::FlatSymbolRefAttr elementDtor;
1536 bool hasThrowingDtor = false;
1537 if (const auto *rd = deleteTy->getAsCXXRecordDecl()) {
1538 if (rd->hasDefinition() && !rd->hasTrivialDestructor()) {
1539 const CXXDestructorDecl *dtor = rd->getDestructor();
1540 if (dtor->getType()->castAs<FunctionProtoType>()->canThrow())
1541 hasThrowingDtor = true;
1542 cir::FuncOp dtorFn =
1543 cgm.getAddrOfCXXStructor(GlobalDecl(dtor, Dtor_Complete));
1544 elementDtor = mlir::FlatSymbolRefAttr::get(builder.getContext(),
1545 dtorFn.getSymNameAttr());
1546 }
1547 }
1548
1549 cir::DeleteArrayOp::create(builder, ptr.getPointer().getLoc(),
1550 ptr.getPointer(), deleteFn, deleteParams,
1551 elementDtor, hasThrowingDtor);
1552 } else {
1553 emitObjectDelete(*this, e, ptr, deleteTy);
1554 }
1555}
1556
1558 // The element type being allocated.
1560
1561 // 1. Build a call to the allocation function.
1562 FunctionDecl *allocator = e->getOperatorNew();
1563
1564 // If there is a brace-initializer, cannot allocate fewer elements than inits.
1565 unsigned minElements = 0;
1566 if (e->isArray() && e->hasInitializer()) {
1567 const Expr *init = e->getInitializer();
1568 const InitListExpr *ile = dyn_cast<InitListExpr>(init);
1569 const CXXParenListInitExpr *cplie = dyn_cast<CXXParenListInitExpr>(init);
1570 const Expr *ignoreParen = init->IgnoreParenImpCasts();
1571 if ((ile && ile->isStringLiteralInit()) ||
1572 isa<StringLiteral>(ignoreParen) || isa<ObjCEncodeExpr>(ignoreParen)) {
1573 minElements =
1575 ->getSize()
1576 .getZExtValue();
1577 } else if (ile || cplie) {
1578 minElements = ile ? ile->getNumInits() : cplie->getInitExprs().size();
1579 }
1580 }
1581
1582 mlir::Value numElements = nullptr;
1583 mlir::Value allocSizeWithoutCookie = nullptr;
1584 mlir::Value allocSize = emitCXXNewAllocSize(
1585 *this, e, minElements, numElements, allocSizeWithoutCookie);
1586 CharUnits allocAlign = getContext().getTypeAlignInChars(allocType);
1587
1588 // Emit the allocation call.
1589 Address allocation = Address::invalid();
1590 CallArgList allocatorArgs;
1591 if (allocator->isReservedGlobalPlacementOperator()) {
1592 // If the allocator is a global placement operator, just
1593 // "inline" it directly.
1594 assert(e->getNumPlacementArgs() == 1);
1595 const Expr *arg = *e->placement_arguments().begin();
1596
1597 LValueBaseInfo baseInfo;
1598 allocation = emitPointerWithAlignment(arg, &baseInfo);
1599
1600 // The pointer expression will, in many cases, be an opaque void*.
1601 // In these cases, discard the computed alignment and use the
1602 // formal alignment of the allocated type.
1603 if (baseInfo.getAlignmentSource() != AlignmentSource::Decl)
1604 allocation = allocation.withAlignment(allocAlign);
1605
1606 // Set up allocatorArgs for the call to operator delete if it's not
1607 // the reserved global operator.
1608 if (e->getOperatorDelete() &&
1610 cgm.errorNYI(e->getSourceRange(),
1611 "emitCXXNewExpr: reserved placement new with delete");
1612 }
1613 } else {
1614 const FunctionProtoType *allocatorType =
1615 allocator->getType()->castAs<FunctionProtoType>();
1616 unsigned paramsToSkip = 0;
1617
1618 // The allocation size is the first argument.
1619 QualType sizeType = getContext().getSizeType();
1620 allocatorArgs.add(RValue::get(allocSize), sizeType);
1621 ++paramsToSkip;
1622
1623 if (allocSize != allocSizeWithoutCookie) {
1624 CharUnits cookieAlign = getSizeAlign(); // FIXME: Ask the ABI.
1625 allocAlign = std::max(allocAlign, cookieAlign);
1626 }
1627
1628 // The allocation alignment may be passed as the second argument.
1629 if (e->passAlignment()) {
1630 // The alignment is always the second positional argument to a
1631 // C++17 aligned allocation function -- right after the size.
1632 constexpr unsigned indexOfAlignArg = 1;
1633 // The corresponding parameter type, if the allocator declares one;
1634 // otherwise fall back to size_t (the underlying type of
1635 // std::align_val_t).
1636 QualType alignValType = sizeType;
1637 if (allocatorType->getNumParams() > indexOfAlignArg)
1638 alignValType = allocatorType->getParamType(indexOfAlignArg);
1639 cir::ConstantOp align = builder.getAlignment(
1640 *currSrcLoc, convertType(alignValType), allocAlign);
1641 allocatorArgs.add(RValue::get(align), alignValType);
1642 ++paramsToSkip;
1643 }
1644
1645 // FIXME: Why do we not pass a CalleeDecl here?
1646 emitCallArgs(allocatorArgs, allocatorType, e->placement_arguments(),
1647 AbstractCallee(), paramsToSkip);
1648 RValue rv =
1649 emitNewDeleteCall(*this, allocator, allocatorType, allocatorArgs);
1650
1651 // Set !heapallocsite metadata on the call to operator new.
1653
1654 // If this was a call to a global replaceable allocation function that does
1655 // not take an alignment argument, the allocator is known to produce storage
1656 // that's suitably aligned for any object that fits, up to a known
1657 // threshold. Otherwise assume it's suitably aligned for the allocated type.
1658 CharUnits allocationAlign = allocAlign;
1659 if (!e->passAlignment() &&
1660 allocator->isReplaceableGlobalAllocationFunction()) {
1661 const TargetInfo &target = cgm.getASTContext().getTargetInfo();
1662 unsigned allocatorAlign = llvm::bit_floor(std::min<uint64_t>(
1663 target.getNewAlign(), getContext().getTypeSize(allocType)));
1664 allocationAlign = std::max(
1665 allocationAlign, getContext().toCharUnitsFromBits(allocatorAlign));
1666 }
1667
1668 mlir::Value allocPtr = rv.getValue();
1669 allocation = Address(
1670 allocPtr, mlir::cast<cir::PointerType>(allocPtr.getType()).getPointee(),
1671 allocationAlign);
1672 }
1673
1674 // Emit a null check on the allocation result if the allocation
1675 // function is allowed to return null (because it has a non-throwing
1676 // exception spec or is the reserved placement new) and we have an
1677 // interesting initializer will be running sanitizers on the initialization.
1678 bool nullCheck = e->shouldNullCheckAllocation() &&
1679 (!allocType.isPODType(getContext()) || e->hasInitializer());
1680
1681 // If there's an operator delete, enter a cleanup to call it if an
1682 // exception is thrown. If we do this, we'll be creating the result pointer
1683 // inside a cleanup scope, either with a bitcast or an offset based on the
1684 // array cookie size. However, we need to return that pointer from outside
1685 // the cleanup scope, so we need to store it in a temporary variable.
1686 bool useNewDeleteCleanup =
1687 e->getOperatorDelete() &&
1689
1690 mlir::Type elementTy;
1691 // For array new, use the allocated type to handle multidimensional arrays
1692 // correctly.
1693 if (e->isArray())
1694 elementTy = convertTypeForMem(e->getAllocatedType());
1695 else
1696 elementTy = convertTypeForMem(allocType);
1697
1698 // Lambda that emits the init sequence: cleanup setup, cookie init,
1699 // bitcast + initializer, and cleanup deactivation.
1700 Address result = Address::invalid();
1701 Address resultPtr = Address::invalid();
1702 auto emitInit = [&]() {
1703 EHScopeStack::stable_iterator operatorDeleteCleanup;
1704 mlir::Operation *cleanupDominator = nullptr;
1705 if (useNewDeleteCleanup) {
1707 enterNewDeleteCleanup(*this, e, allocation, allocSize, allocAlign,
1708 allocatorArgs);
1709 operatorDeleteCleanup = ehStack.stable_begin();
1710 cleanupDominator =
1711 cir::UnreachableOp::create(builder, getLoc(e->getSourceRange()))
1712 .getOperation();
1713 resultPtr = createTempAlloca(builder.getPointerTo(elementTy),
1714 allocation.getAlignment(),
1715 getLoc(e->getSourceRange()), "__new_result");
1716 }
1717
1718 if (allocSize != allocSizeWithoutCookie) {
1719 assert(e->isArray());
1720 allocation = cgm.getCXXABI().initializeArrayCookie(
1721 *this, allocation, numElements, e, allocType);
1722 }
1723
1724 result = builder.createElementBitCast(getLoc(e->getSourceRange()),
1725 allocation, elementTy);
1726
1727 // Store the result pointer before initialization so that it is available
1728 // to the cleanup if the initializer throws.
1729 if (resultPtr.isValid())
1730 builder.createStore(getLoc(e->getSourceRange()), result.getPointer(),
1731 resultPtr);
1732
1733 // Passing pointer through launder.invariant.group to avoid propagation of
1734 // vptrs information which may be included in previous type. To not break
1735 // LTO with different optimizations levels, we do it regardless of
1736 // optimization level.
1737 if (cgm.getCodeGenOpts().StrictVTablePointers &&
1738 allocator->isReservedGlobalPlacementOperator())
1739 cgm.errorNYI(e->getSourceRange(),
1740 "emitCXXNewExpr: strict vtable pointers");
1741
1743
1744 emitNewInitializer(*this, e, allocType, elementTy, result, numElements,
1745 allocSizeWithoutCookie);
1746
1747 // Deactivate the 'operator delete' cleanup if we finished
1748 // initialization.
1749 if (useNewDeleteCleanup) {
1750 deactivateCleanupBlock(operatorDeleteCleanup, cleanupDominator);
1751 cleanupDominator->erase();
1752 cir::LoadOp loadResult =
1753 builder.createLoad(getLoc(e->getSourceRange()), resultPtr);
1754 result = result.withPointer(loadResult.getResult());
1755 }
1756 };
1757
1758 cir::IfOp nullCheckOp;
1759 if (nullCheck) {
1760 mlir::Value isNotNull = builder.createPtrIsNotNull(allocation.getPointer());
1761 nullCheckOp =
1762 cir::IfOp::create(builder, getLoc(e->getSourceRange()), isNotNull,
1763 /*withElseRegion=*/false,
1764 /*thenBuilder=*/
1765 [&](mlir::OpBuilder &, mlir::Location loc) {
1766 emitInit();
1767 builder.createYield(loc);
1768 });
1769 } else {
1770 emitInit();
1771 }
1772
1773 mlir::Value resultValue = result.getPointer();
1774
1775 if (nullCheck) {
1776 mlir::Type resultTy = resultValue.getType();
1777
1778 // If we needed a NewDeleteCleanup, allocation may have been modified
1779 // inside the cir.if (e.g. by cookie adjustment). Use the result stored
1780 // in the alloca instead, since the alloca dominates this point.
1781 mlir::Value trueVal;
1782 if (useNewDeleteCleanup) {
1783 trueVal = builder.createLoad(getLoc(e->getSourceRange()), resultPtr)
1784 .getResult();
1785 } else {
1786 trueVal = allocation.getPointer();
1787 }
1788 if (trueVal.getType() != resultTy)
1789 trueVal = builder.createBitcast(trueVal, resultTy);
1790 mlir::Value nullPtr =
1791 builder.getNullPtr(resultTy, getLoc(e->getSourceRange())).getResult();
1792 resultValue =
1793 builder.createSelect(getLoc(e->getSourceRange()),
1794 nullCheckOp.getCondition(), trueVal, nullPtr);
1795 }
1796
1797 return resultValue;
1798}
1799
1801 mlir::Value ptr, QualType deleteTy) {
1803
1804 const auto *deleteFTy = deleteFD->getType()->castAs<FunctionProtoType>();
1805 CallArgList deleteArgs;
1806
1807 UsualDeleteParams params = deleteFD->getUsualDeleteParams();
1808 auto paramTypeIter = deleteFTy->param_type_begin();
1809
1810 // Pass std::type_identity tag if present
1812 cgm.errorNYI(deleteFD->getSourceRange(),
1813 "emitDeleteCall: type aware delete");
1814
1815 // Pass the pointer itself.
1816 QualType argTy = *paramTypeIter;
1817 std::advance(paramTypeIter, 1);
1818 mlir::Value deletePtr =
1819 builder.createBitcast(ptr.getLoc(), ptr, convertType(argTy));
1820 deleteArgs.add(RValue::get(deletePtr), argTy);
1821
1822 // Pass the std::destroying_delete tag if present.
1823 if (params.DestroyingDelete) {
1824 QualType tagType = *paramTypeIter;
1825 std::advance(paramTypeIter, 1);
1826 Address tagAddr =
1827 createMemTemp(tagType, ptr.getLoc(), "destroying.delete.tag");
1828 deleteArgs.add(RValue::getAggregate(tagAddr), tagType);
1829 }
1830
1831 // Pass the size if the delete function has a size_t parameter.
1832 if (params.Size) {
1833 QualType sizeType = *paramTypeIter;
1834 std::advance(paramTypeIter, 1);
1835 CharUnits deleteTypeSize = getContext().getTypeSizeInChars(deleteTy);
1836 assert(mlir::isa<cir::IntType>(convertType(sizeType)) &&
1837 "expected cir::IntType");
1838 cir::ConstantOp size = builder.getConstInt(
1839 *currSrcLoc, convertType(sizeType), deleteTypeSize.getQuantity());
1840
1841 deleteArgs.add(RValue::get(size), sizeType);
1842 }
1843
1844 // Pass the alignment if the delete function has an align_val_t parameter.
1845 if (isAlignedAllocation(params.Alignment)) {
1846 QualType alignValType = *paramTypeIter++;
1847 CharUnits deleteTypeAlign =
1848 getContext().toCharUnitsFromBits(getContext().getTypeAlignIfKnown(
1849 deleteTy, /*NeedsPreferredAlignment=*/true));
1850 cir::ConstantOp align = builder.getAlignment(
1851 *currSrcLoc, convertType(alignValType), deleteTypeAlign);
1852 deleteArgs.add(RValue::get(align), alignValType);
1853 }
1854
1855 assert(paramTypeIter == deleteFTy->param_type_end() &&
1856 "unknown parameter to usual delete function");
1857
1858 // Emit the call to delete.
1859 emitNewDeleteCall(*this, deleteFD, deleteFTy, deleteArgs);
1860}
1861
1863 mlir::Location loc, QualType destTy) {
1864 mlir::Type destCIRTy = cgf.convertType(destTy);
1865 assert(mlir::isa<cir::PointerType>(destCIRTy) &&
1866 "result of dynamic_cast should be a ptr");
1867
1868 if (!destTy->isPointerType()) {
1869 mlir::Region *currentRegion = cgf.getBuilder().getBlock()->getParent();
1870 /// C++ [expr.dynamic.cast]p9:
1871 /// A failed cast to reference type throws std::bad_cast
1872 cgf.cgm.getCXXABI().emitBadCastCall(cgf, loc);
1873
1874 // The call to bad_cast will terminate the current block. Create a new block
1875 // to hold any follow up code.
1876 cgf.getBuilder().createBlock(currentRegion, currentRegion->end());
1877 }
1878
1879 return cgf.getBuilder().getNullPtr(destCIRTy, loc);
1880}
1881
1883 const CXXDynamicCastExpr *dce) {
1884 mlir::Location loc = getLoc(dce->getSourceRange());
1885
1886 cgm.emitExplicitCastExprType(dce, this);
1887 QualType destTy = dce->getTypeAsWritten();
1888 QualType srcTy = dce->getSubExpr()->getType();
1889
1890 // C++ [expr.dynamic.cast]p7:
1891 // If T is "pointer to cv void," then the result is a pointer to the most
1892 // derived object pointed to by v.
1893 bool isDynCastToVoid = destTy->isVoidPointerType();
1894 bool isRefCast = destTy->isReferenceType();
1895
1896 QualType srcRecordTy;
1897 QualType destRecordTy;
1898 if (isDynCastToVoid) {
1899 srcRecordTy = srcTy->getPointeeType();
1900 // No destRecordTy.
1901 } else if (const PointerType *destPTy = destTy->getAs<PointerType>()) {
1902 srcRecordTy = srcTy->castAs<PointerType>()->getPointeeType();
1903 destRecordTy = destPTy->getPointeeType();
1904 } else {
1905 srcRecordTy = srcTy;
1906 destRecordTy = destTy->castAs<ReferenceType>()->getPointeeType();
1907 }
1908
1909 assert(srcRecordTy->isRecordType() && "source type must be a record type!");
1911
1912 if (dce->isAlwaysNull())
1913 return emitDynamicCastToNull(*this, loc, destTy);
1914
1915 auto destCirTy = mlir::cast<cir::PointerType>(convertType(destTy));
1916 return cgm.getCXXABI().emitDynamicCast(*this, loc, srcRecordTy, destRecordTy,
1917 destCirTy, isRefCast, thisAddr);
1918}
1919
1920static mlir::Value emitCXXTypeidFromVTable(CIRGenFunction &cgf, const Expr *e,
1921 mlir::Type typeInfoPtrTy,
1922 bool hasNullCheck) {
1923 Address thisPtr = cgf.emitLValue(e).getAddress();
1924 QualType srcType = e->getType();
1925
1926 // C++ [class.cdtor]p4:
1927 // If the operand of typeid refers to the object under construction or
1928 // destruction and the static type of the operand is neither the constructor
1929 // or destructor’s class nor one of its bases, the behavior is undefined.
1931
1932 if (hasNullCheck && cgf.cgm.getCXXABI().shouldTypeidBeNullChecked(srcType)) {
1933 mlir::Value isThisNull =
1934 cgf.getBuilder().createPtrIsNull(thisPtr.getPointer());
1935 // We don't really care about the value, we just want to make sure the
1936 // 'true' side calls bad-type-id.
1937 cir::IfOp::create(
1938 cgf.getBuilder(), cgf.getLoc(e->getSourceRange()), isThisNull,
1939 /*withElseRegion=*/false, [&](mlir::OpBuilder &, mlir::Location loc) {
1940 cgf.cgm.getCXXABI().emitBadTypeidCall(cgf, loc);
1941 });
1942 }
1943
1944 return cgf.cgm.getCXXABI().emitTypeid(cgf, srcType, thisPtr, typeInfoPtrTy);
1945}
1946
1948 mlir::Location loc = getLoc(e->getSourceRange());
1949 mlir::Type resultType = cir::PointerType::get(convertType(e->getType()));
1951 : e->getExprOperand()->getType();
1952
1953 // If the non-default global var address space is not default, we need to do
1954 // an address-space cast here.
1956
1957 // C++ [expr.typeid]p2:
1958 // When typeid is applied to a glvalue expression whose type is a
1959 // polymorphic class type, the result refers to a std::type_info object
1960 // representing the type of the most derived object (that is, the dynamic
1961 // type) to which the glvalue refers.
1962 // If the operand is already most derived object, no need to look up vtable.
1963 if (!e->isTypeOperand() && e->isPotentiallyEvaluated() &&
1965 return emitCXXTypeidFromVTable(*this, e->getExprOperand(), resultType,
1966 e->hasNullCheck());
1967
1968 auto typeInfo =
1969 cast<cir::GlobalViewAttr>(cgm.getAddrOfRTTIDescriptor(loc, ty));
1970 // `getAddrOfRTTIDescriptor` lies to us and always gives us a uint8ptr as its
1971 // type, however we need the value of the actual global to call the
1972 // get-global-op, so look it up here.
1973 auto typeInfoGlobal =
1974 cast<cir::GlobalOp>(cgm.getGlobalValue(typeInfo.getSymbol().getValue()));
1975 auto getTypeInfo = cir::GetGlobalOp::create(
1976 builder, loc, builder.getPointerTo(typeInfoGlobal.getSymType()),
1977 typeInfoGlobal.getSymName());
1978 // The ABI is just generating these sometimes as ptr to u8, but they are
1979 // simply a representation of the type_info. So we have to cast this, if
1980 // necessary (createBitcast is a noop if the types match).
1981 return builder.createBitcast(getTypeInfo, resultType);
1982}
static void emit(Program &P, llvm::SmallVectorImpl< std::byte > &Code, const T &Val, bool &Success)
Helper to write bytecode and bail out if 32-bit offsets become invalid.
static 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 mlir::Value emitCXXTypeidFromVTable(CIRGenFunction &cgf, const Expr *e, mlir::Type typeInfoPtrTy, bool hasNullCheck)
static void emitObjectDelete(CIRGenFunction &cgf, const CXXDeleteExpr *de, Address ptr, QualType elementType)
Emit the code for deleting a single object.
static void emitNullBaseClassInitialization(CIRGenFunction &cgf, Address destPtr, const CXXRecordDecl *base)
static void enterNewDeleteCleanup(CIRGenFunction &cgf, const CXXNewExpr *e, Address newPtr, mlir::Value allocSize, CharUnits allocAlign, const CallArgList &newArgs)
Enter a cleanup to call 'operator delete' if the initializer in a new-expression throws.
static mlir::Value emitCXXNewAllocSize(CIRGenFunction &cgf, const CXXNewExpr *e, unsigned minElements, mlir::Value &numElements, mlir::Value &sizeWithoutCookie)
static void 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.
tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName="<stdin>")
Clean up any erroneous/redundant code in the given Ranges in Code.
Defines an enumeration for C++ overloaded operators.
static QualType getPointeeType(const MemRegion *R)
__device__ __2f16 b
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:229
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:811
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const
Return number of constant array elements.
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:3784
A builtin binary operation expression such as "x + y" or "x <= y".
Definition Expr.h:4041
Expr * getLHS() const
Definition Expr.h:4091
Expr * getRHS() const
Definition Expr.h:4093
Opcode getOpcode() const
Definition Expr.h:4086
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::LoadOp createAlignedLoad(mlir::Location loc, mlir::Type ty, mlir::Value ptr, llvm::MaybeAlign align)
bool isNullValue(mlir::Attribute attr) const
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, mlir::IntegerAttr align={}, cir::SyncScopeKindAttr scope={}, cir::MemOrderAttr order={})
cir::ConstantOp getConstInt(mlir::Location loc, llvm::APSInt intVal)
cir::IntType getUIntNTy(int n)
virtual void emitVirtualObjectDelete(CIRGenFunction &cgf, const CXXDeleteExpr *de, Address ptr, QualType elementType, const CXXDestructorDecl *dtor)=0
virtual const clang::CXXRecordDecl * getThisArgumentTypeForMethod(const clang::CXXMethodDecl *md)
Get the type of the implicit "this" parameter used by a method.
virtual bool shouldTypeidBeNullChecked(QualType srcTy)=0
virtual mlir::Value emitTypeid(CIRGenFunction &cgf, QualType srcTy, Address thisPtr, mlir::Type typeInfoPtrTy)=0
virtual void emitBadCastCall(CIRGenFunction &cgf, mlir::Location loc)=0
virtual CharUnits getArrayCookieSize(const CXXNewExpr *e)
Returns the extra size required in order to store the array cookie for the given new-expression.
static CIRGenCallee forDirect(mlir::Operation *funcPtr, const CIRGenCalleeInfo &abstractInfo=CIRGenCalleeInfo())
Definition CIRGenCall.h:92
static CIRGenCallee forVirtual(const clang::CallExpr *ce, clang::GlobalDecl md, Address addr, cir::FuncType fTy)
Definition CIRGenCall.h:154
An abstract representation of regular/ObjC call/message targets.
void emitCallArgs(CallArgList &args, PrototypeWrapper prototype, llvm::iterator_range< clang::CallExpr::const_arg_iterator > argRange, AbstractCallee callee=AbstractCallee(), unsigned paramsToSkip=0)
mlir::Type convertType(clang::QualType t)
static cir::TypeEvaluationKind getEvaluationKind(clang::QualType type)
Return the cir::TypeEvaluationKind of QualType type.
clang::GlobalDecl curGD
The GlobalDecl for the current function being compiled or the global variable currently being initial...
CIRGenTypes & getTypes() const
Address emitPointerWithAlignment(const clang::Expr *expr, LValueBaseInfo *baseInfo=nullptr)
Given an expression with a pointer type, emit the value and compute our best estimate of the alignmen...
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.
RValue emitCXXMemberOrOperatorCall(const clang::CXXMethodDecl *md, const CIRGenCallee &callee, ReturnValueSlot returnValue, mlir::Value thisPtr, mlir::Value implicitParam, clang::QualType implicitParamTy, const clang::CallExpr *ce, CallArgList *rtlArgs)
void emitNullInitialization(mlir::Location loc, Address destPtr, QualType ty)
RValue emitCUDAKernelCallExpr(const CUDAKernelCallExpr *expr, ReturnValueSlot returnValue)
EHScopeStack ehStack
Tracks function scope overall cleanup handling.
void emitNewArrayInitializer(const CXXNewExpr *e, QualType elementType, mlir::Type elementTy, Address beginPtr, mlir::Value numElements, mlir::Value allocSizeWithoutCookie)
clang::SanitizerSet sanOpts
Sanitizers enabled for this function.
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 emitScalarInit(const clang::Expr *init, mlir::Location loc, LValue lvalue, bool capturedByInit=false)
RValue emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, const CallArgList &args, cir::CIRCallOpInterface *callOp, mlir::Location loc)
void deactivateCleanupBlock(EHScopeStack::stable_iterator cleanup, mlir::Operation *dominatingIP)
Deactivates the given cleanup block.
mlir::Value emitScalarExpr(const clang::Expr *e, bool ignoreResultAssign=false)
Emit the computation of the specified expression of scalar type.
CIRGenBuilderTy & getBuilder()
Destroyer * getDestroyer(clang::QualType::DestructionKind kind)
void popCleanupBlock(bool forDeactivation=false)
Pop a cleanup block from the stack.
void emitComplexExprIntoLValue(const Expr *e, LValue dest, bool isInit)
LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)
void emitCXXDestructorCall(const CXXDestructorDecl *dd, CXXDtorType type, bool forVirtualBase, bool delegating, Address thisAddr, QualType thisTy)
RValue emitNewOrDeleteBuiltinCall(const FunctionProtoType *type, const CallExpr *callExpr, OverloadedOperatorKind op)
void emitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, const clang::ArrayType *arrayType, Address arrayBegin, const CXXConstructExpr *e, bool newPointerIsChecked, bool zeroInitialize=false)
Emit a loop to call a particular constructor for each of several members of an array.
std::optional< mlir::Location > currSrcLoc
Use to track source locations across nested visitor traversals.
clang::ASTContext & getContext() const
RValue emitCXXMemberOrOperatorMemberCallExpr(const clang::CallExpr *ce, const clang::CXXMethodDecl *md, ReturnValueSlot returnValue, bool hasQualifier, clang::NestedNameSpecifier qualifier, bool isArrow, const clang::Expr *base)
void emitCXXDeleteExpr(const CXXDeleteExpr *e)
RValue emitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *e, const CXXMethodDecl *md, ReturnValueSlot returnValue)
void emitIgnoredExpr(const clang::Expr *e)
Emit code to compute the specified expression, ignoring the result.
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.
cir::FuncOp getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType=nullptr, bool forVTable=false, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
Return the address of the given function.
const cir::CIRDataLayout getDataLayout() const
CIRGenCXXABI & getCXXABI() const
const CIRGenFunctionInfo & arrangeFreeFunctionCall(const CallArgList &args, const FunctionType *fnType)
clang::CanQualType deriveThisType(const clang::CXXRecordDecl *rd, const clang::CXXMethodDecl *md)
Derives the 'this' type for CIRGen purposes, i.e.
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
Definition CIRGenCall.h:248
void add(RValue rvalue, clang::QualType type)
Definition CIRGenCall.h:239
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:260
Represents a call to a CUDA kernel function.
Definition ExprCXX.h:238
Represents a call to a C++ constructor.
Definition ExprCXX.h:1552
bool isElidable() const
Whether this construction is elidable.
Definition ExprCXX.h:1621
Expr * getArg(unsigned Arg)
Return the specified argument.
Definition ExprCXX.h:1695
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
Definition ExprCXX.h:1654
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition ExprCXX.h:1615
CXXConstructionKind getConstructionKind() const
Determine whether this constructor is actually constructing a base class (rather than a complete obje...
Definition ExprCXX.h:1663
Represents a C++ constructor within a class.
Definition DeclCXX.h:2620
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Definition DeclCXX.cpp:3047
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition ExprCXX.h:2630
FunctionDecl * getOperatorDelete() const
Definition ExprCXX.h:2669
bool isArrayForm() const
Definition ExprCXX.h:2656
QualType getDestroyedType() const
Retrieve the type being destroyed.
Definition ExprCXX.cpp:343
Represents a C++ destructor within a class.
Definition DeclCXX.h:2882
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
Definition ExprCXX.h:485
bool isAlwaysNull() const
isAlwaysNull - Return whether the result of the dynamic_cast is proven to always be null.
Definition ExprCXX.cpp:845
Represents a call to a member function that may be written either with member call syntax (e....
Definition ExprCXX.h:183
SourceLocation getExprLoc() const LLVM_READONLY
Definition ExprCXX.h:224
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2132
bool isVirtual() const
Definition DeclCXX.h:2187
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition DeclCXX.h:2271
bool isInstance() const
Definition DeclCXX.h:2159
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:2522
CXXMethodDecl * getCorrespondingMethodInClass(const CXXRecordDecl *RD, bool MayBeBase=false)
Find the method in RD that corresponds to this one.
Definition DeclCXX.cpp:2468
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition ExprCXX.h:2359
bool isArray() const
Definition ExprCXX.h:2468
llvm::iterator_range< arg_iterator > placement_arguments()
Definition ExprCXX.h:2576
QualType getAllocatedType() const
Definition ExprCXX.h:2438
unsigned getNumImplicitArgs() const
Definition ExprCXX.h:2515
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:2473
ImplicitAllocationParameters implicitAllocationParameters() const
Provides the full set of information about expected implicit parameters in this call.
Definition ExprCXX.h:2566
bool hasInitializer() const
Whether this new-expression has any initializer at all.
Definition ExprCXX.h:2528
bool shouldNullCheckAllocation() const
True if the allocation result needs to be null-checked.
Definition ExprCXX.cpp:331
bool passAlignment() const
Indicates whether the required alignment should be implicitly passed to the allocation function.
Definition ExprCXX.h:2555
FunctionDecl * getOperatorDelete() const
Definition ExprCXX.h:2465
unsigned getNumPlacementArgs() const
Definition ExprCXX.h:2498
SourceRange getSourceRange() const
Definition ExprCXX.h:2614
FunctionDecl * getOperatorNew() const
Definition ExprCXX.h:2463
Expr * getInitializer()
The initializer of this new-expression.
Definition ExprCXX.h:2537
A call to an overloaded operator written using operator syntax.
Definition ExprCXX.h:85
Represents a list-initialization with parenthesis.
Definition ExprCXX.h:5141
MutableArrayRef< Expr * > getInitExprs()
Definition ExprCXX.h:5181
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
Definition ExprCXX.h:2749
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:1186
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
Definition DeclCXX.cpp:2127
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Definition ExprCXX.h:852
bool isTypeOperand() const
Definition ExprCXX.h:888
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Definition ExprCXX.cpp:166
Expr * getExprOperand() const
Definition ExprCXX.h:899
SourceRange getSourceRange() const LLVM_READONLY
Definition ExprCXX.h:906
bool isMostDerived(const ASTContext &Context) const
Best-effort check if the expression operand refers to a most derived object.
Definition ExprCXX.cpp:149
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr....
Definition ExprCXX.cpp:134
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:205
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2946
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition Expr.h:3150
arg_iterator arg_begin()
Definition Expr.h:3203
arg_iterator arg_end()
Definition Expr.h:3206
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition Expr.h:3129
Expr * getCallee()
Definition Expr.h:3093
arg_range arguments()
Definition Expr.h:3198
Expr * getSubExpr()
Definition Expr.h:3729
CharUnits - 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:207
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition CharUnits.h:185
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:214
bool isOne() const
isOne - Test whether the quantity equals one.
Definition CharUnits.h:125
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition CharUnits.h:63
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Definition CharUnits.h:53
Represents the canonical version of C arrays with a specified constant size.
Definition TypeBase.h:3822
The results of name lookup within a DeclContext.
Definition DeclBase.h:1395
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:435
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:3958
This represents one expression.
Definition Expr.h:112
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:69
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition Expr.cpp:3097
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3093
Expr * IgnoreParenBaseCasts() LLVM_READONLY
Skip past any parentheses and derived-to-base casts until reaching a fixed point.
Definition Expr.cpp:3119
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:3260
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition Expr.cpp:282
QualType getType() const
Definition Expr.h:144
Represents a member of a struct/union/class.
Definition Decl.h:3182
Represents a function declaration or definition.
Definition Decl.h:2018
bool isDestroyingOperatorDelete() const
Determine whether this is a destroying operator delete.
Definition Decl.cpp:3525
QualType getReturnType() const
Definition Decl.h:2863
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition Decl.h:2395
bool isReplaceableGlobalAllocationFunction(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
Definition Decl.h:2612
UsualDeleteParams getUsualDeleteParams() const
Definition Decl.cpp:3541
bool isReservedGlobalPlacementOperator() const
Determines whether this operator new or delete is one of the reserved global placement operators: voi...
Definition Decl.cpp:3377
bool isDefaulted() const
Whether this function is defaulted.
Definition Decl.h:2403
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4543
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5369
unsigned getNumParams() const
Definition TypeBase.h:5647
QualType getParamType(unsigned i) const
Definition TypeBase.h:5649
CanThrowResult canThrow() const
Determine whether this function type has a non-throwing exception specification.
Definition Type.cpp:3968
GlobalDecl - represents a global declaration.
Definition GlobalDecl.h:57
const Decl * getDecl() const
Definition GlobalDecl.h:106
Represents an implicitly-generated value initialization of an object of a given type.
Definition Expr.h:6057
Describes an C or C++ initializer list.
Definition Expr.h:5302
bool isStringLiteralInit() const
Is this an initializer for an array of characters, initialized by a string literal or an @encode?
Definition Expr.cpp:2455
unsigned getNumInits() const
Definition Expr.h:5335
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
Definition Expr.h:5405
const Expr * getInit(unsigned Init) const
Definition Expr.h:5357
ArrayRef< Expr * > inits() const
Definition Expr.h:5355
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition TypeBase.h:3715
QualType getPointeeType() const
Definition TypeBase.h:3733
This represents a decl that may have a name.
Definition Decl.h:274
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
ObjCEncodeExpr, used for @encode in Objective-C.
Definition ExprObjC.h:441
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition TypeBase.h:3390
A (possibly-)qualified type.
Definition TypeBase.h:937
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1004
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition TypeBase.h:8485
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
Definition TypeBase.h:1453
QualType getCanonicalType() const
Definition TypeBase.h:8497
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
Definition TypeBase.h:1560
bool isPODType(const ASTContext &Context) const
Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
Definition Type.cpp:2788
bool hasStrongOrWeakObjCLifetime() const
Definition TypeBase.h:1461
Represents a struct/union/class.
Definition Decl.h:4347
field_range fields() const
Definition Decl.h:4550
RecordDecl * getDefinitionOrSelf() const
Definition Decl.h:4535
Base for LValueReferenceType and RValueReferenceType.
Definition TypeBase.h:3635
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:1802
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4887
bool isUnion() const
Definition Decl.h:3950
Exposes information about the current target.
Definition TargetInfo.h:227
unsigned getNewAlign() const
Return the largest alignment for which a suitably-sized allocation with 'operator new(size_t)' is gua...
Definition TargetInfo.h:767
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:3569
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:8785
bool isVoidPointerType() const
Definition Type.cpp:749
bool isPointerType() const
Definition TypeBase.h:8682
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9342
bool isReferenceType() const
Definition TypeBase.h:8706
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:1958
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:789
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition TypeBase.h:9328
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2983
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9275
bool isRecordType() const
Definition TypeBase.h:8809
QualType getType() const
Definition Decl.h:723
@ 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:201
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
CXXCtorType
C++ constructor types.
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:2273
bool isAlignedAllocation(AlignedAllocationMode Mode)
Definition ExprCXX.h:2269
AlignedAllocationMode
Definition ExprCXX.h:2267
@ Dtor_Complete
Complete object dtor.
Definition ABI.h:36
bool isTypeAwareAllocation(TypeAwareAllocationMode Mode)
Definition ExprCXX.h:2257
TypeAwareAllocationMode
Definition ExprCXX.h:2255
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 opCallMustTail()
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:2348
TypeAwareAllocationMode TypeAwareDelete
Definition ExprCXX.h:2349
AlignedAllocationMode Alignment
Definition ExprCXX.h:2352