clang 22.0.0git
CIRGenClass.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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 C++ code generation of classes
10//
11//===----------------------------------------------------------------------===//
12
13#include "CIRGenCXXABI.h"
14#include "CIRGenFunction.h"
15#include "CIRGenValue.h"
16
18#include "clang/AST/ExprCXX.h"
20#include "clang/AST/Type.h"
22
23using namespace clang;
24using namespace clang::CIRGen;
25
26/// Checks whether the given constructor is a valid subject for the
27/// complete-to-base constructor delegation optimization, i.e. emitting the
28/// complete constructor as a simple call to the base constructor.
30 const CXXConstructorDecl *ctor) {
31 // Currently we disable the optimization for classes with virtual bases
32 // because (1) the address of parameter variables need to be consistent across
33 // all initializers but (2) the delegate function call necessarily creates a
34 // second copy of the parameter variable.
35 //
36 // The limiting example (purely theoretical AFAIK):
37 // struct A { A(int &c) { c++; } };
38 // struct A : virtual A {
39 // B(int count) : A(count) { printf("%d\n", count); }
40 // };
41 // ...although even this example could in principle be emitted as a delegation
42 // since the address of the parameter doesn't escape.
43 if (ctor->getParent()->getNumVBases())
44 return false;
45
46 // We also disable the optimization for variadic functions because it's
47 // impossible to "re-pass" varargs.
48 if (ctor->getType()->castAs<FunctionProtoType>()->isVariadic())
49 return false;
50
51 // FIXME: Decide if we can do a delegation of a delegating constructor.
52 if (ctor->isDelegatingConstructor())
53 return false;
54
55 return true;
56}
57
59 CXXCtorInitializer *memberInit,
60 LValue &lhs) {
61 FieldDecl *field = memberInit->getAnyMember();
62 if (memberInit->isIndirectMemberInitializer()) {
63 // If we are initializing an anonymous union field, drill down to the field.
64 IndirectFieldDecl *indirectField = memberInit->getIndirectMember();
65 for (const auto *nd : indirectField->chain()) {
66 auto *fd = cast<clang::FieldDecl>(nd);
67 lhs = cgf.emitLValueForFieldInitialization(lhs, fd, fd->getName());
68 }
69 } else {
70 lhs = cgf.emitLValueForFieldInitialization(lhs, field, field->getName());
71 }
72}
73
75 const CXXRecordDecl *classDecl,
76 CXXCtorInitializer *memberInit,
77 const CXXConstructorDecl *constructor,
78 FunctionArgList &args) {
79 assert(memberInit->isAnyMemberInitializer() &&
80 "Must have member initializer!");
81 assert(memberInit->getInit() && "Must have initializer!");
82
84
85 // non-static data member initializers
86 FieldDecl *field = memberInit->getAnyMember();
87 QualType fieldType = field->getType();
88
89 mlir::Value thisPtr = cgf.loadCXXThis();
90 CanQualType recordTy = cgf.getContext().getCanonicalTagType(classDecl);
91
92 // If a base constructor is being emitted, create an LValue that has the
93 // non-virtual alignment.
94 LValue lhs = (cgf.curGD.getCtorType() == Ctor_Base)
95 ? cgf.makeNaturalAlignPointeeAddrLValue(thisPtr, recordTy)
96 : cgf.makeNaturalAlignAddrLValue(thisPtr, recordTy);
97
98 emitLValueForAnyFieldInitialization(cgf, memberInit, lhs);
99
100 // Special case: If we are in a copy or move constructor, and we are copying
101 // an array off PODs or classes with trivial copy constructors, ignore the AST
102 // and perform the copy we know is equivalent.
103 // FIXME: This is hacky at best... if we had a bit more explicit information
104 // in the AST, we could generalize it more easily.
105 const ConstantArrayType *array =
106 cgf.getContext().getAsConstantArrayType(fieldType);
107 if (array && constructor->isDefaulted() &&
108 constructor->isCopyOrMoveConstructor()) {
109 QualType baseElementTy = cgf.getContext().getBaseElementType(array);
110 // NOTE(cir): CodeGen allows record types to be memcpy'd if applicable,
111 // whereas ClangIR wants to represent all object construction explicitly.
112 if (!baseElementTy->isRecordType()) {
113 cgf.cgm.errorNYI(memberInit->getSourceRange(),
114 "emitMemberInitializer: array of non-record type");
115 return;
116 }
117 }
118
119 cgf.emitInitializerForField(field, lhs, memberInit->getInit());
120}
121
123 const Type *baseType = baseInit->getBaseClass();
124 const auto *baseClassDecl = baseType->castAsCXXRecordDecl();
125 return baseClassDecl->isDynamicClass();
126}
127
128namespace {
129/// Call the destructor for a direct base class.
130struct CallBaseDtor final : EHScopeStack::Cleanup {
131 const CXXRecordDecl *baseClass;
132 bool baseIsVirtual;
133 CallBaseDtor(const CXXRecordDecl *base, bool baseIsVirtual)
134 : baseClass(base), baseIsVirtual(baseIsVirtual) {}
135
136 void emit(CIRGenFunction &cgf) override {
137 const CXXRecordDecl *derivedClass =
138 cast<CXXMethodDecl>(cgf.curFuncDecl)->getParent();
139
140 const CXXDestructorDecl *d = baseClass->getDestructor();
141 // We are already inside a destructor, so presumably the object being
142 // destroyed should have the expected type.
143 QualType thisTy = d->getFunctionObjectParameterType();
144 assert(cgf.currSrcLoc && "expected source location");
145 Address addr = cgf.getAddressOfDirectBaseInCompleteClass(
146 *cgf.currSrcLoc, cgf.loadCXXThisAddress(), derivedClass, baseClass,
147 baseIsVirtual);
148 cgf.emitCXXDestructorCall(d, Dtor_Base, baseIsVirtual,
149 /*delegating=*/false, addr, thisTy);
150 }
151};
152
153/// A visitor which checks whether an initializer uses 'this' in a
154/// way which requires the vtable to be properly set.
155struct DynamicThisUseChecker
156 : ConstEvaluatedExprVisitor<DynamicThisUseChecker> {
157 using super = ConstEvaluatedExprVisitor<DynamicThisUseChecker>;
158
159 bool usesThis = false;
160
161 DynamicThisUseChecker(const ASTContext &c) : super(c) {}
162
163 // Black-list all explicit and implicit references to 'this'.
164 //
165 // Do we need to worry about external references to 'this' derived
166 // from arbitrary code? If so, then anything which runs arbitrary
167 // external code might potentially access the vtable.
168 void VisitCXXThisExpr(const CXXThisExpr *e) { usesThis = true; }
169};
170} // end anonymous namespace
171
172static bool baseInitializerUsesThis(ASTContext &c, const Expr *init) {
173 DynamicThisUseChecker checker(c);
174 checker.Visit(init);
175 return checker.usesThis;
176}
177
178/// Gets the address of a direct base class within a complete object.
179/// This should only be used for (1) non-virtual bases or (2) virtual bases
180/// when the type is known to be complete (e.g. in complete destructors).
181///
182/// The object pointed to by 'thisAddr' is assumed to be non-null.
184 mlir::Location loc, Address thisAddr, const CXXRecordDecl *derived,
185 const CXXRecordDecl *base, bool baseIsVirtual) {
186 // 'thisAddr' must be a pointer (in some address space) to Derived.
187 assert(thisAddr.getElementType() == convertType(derived));
188
189 // Compute the offset of the virtual base.
190 CharUnits offset;
191 const ASTRecordLayout &layout = getContext().getASTRecordLayout(derived);
192 if (baseIsVirtual)
193 offset = layout.getVBaseClassOffset(base);
194 else
195 offset = layout.getBaseClassOffset(base);
196
197 return builder.createBaseClassAddr(loc, thisAddr, convertType(base),
198 offset.getQuantity(),
199 /*assumeNotNull=*/true);
200}
201
203 const CXXRecordDecl *classDecl,
204 CXXCtorInitializer *baseInit) {
205 assert(curFuncDecl && "loading 'this' without a func declaration?");
207
208 assert(baseInit->isBaseInitializer() && "Must have base initializer!");
209
210 Address thisPtr = loadCXXThisAddress();
211
212 const Type *baseType = baseInit->getBaseClass();
213 const auto *baseClassDecl = baseType->castAsCXXRecordDecl();
214
215 bool isBaseVirtual = baseInit->isBaseVirtual();
216
217 // If the initializer for the base (other than the constructor
218 // itself) accesses 'this' in any way, we need to initialize the
219 // vtables.
220 if (baseInitializerUsesThis(getContext(), baseInit->getInit()))
221 initializeVTablePointers(loc, classDecl);
222
223 // We can pretend to be a complete class because it only matters for
224 // virtual bases, and we only do virtual bases for complete ctors.
226 loc, thisPtr, classDecl, baseClassDecl, isBaseVirtual);
230 getOverlapForBaseInit(classDecl, baseClassDecl, isBaseVirtual));
231
232 emitAggExpr(baseInit->getInit(), aggSlot);
233
235}
236
237/// This routine generates necessary code to initialize base classes and
238/// non-static data members belonging to this constructor.
240 CXXCtorType ctorType,
241 FunctionArgList &args) {
242 if (cd->isDelegatingConstructor()) {
244 return;
245 }
246
247 const CXXRecordDecl *classDecl = cd->getParent();
248
249 // Virtual base initializers aren't needed if:
250 // - This is a base ctor variant
251 // - There are no vbases
252 // - The class is abstract, so a complete object of it cannot be constructed
253 //
254 // The check for an abstract class is necessary because sema may not have
255 // marked virtual base destructors referenced.
256 bool constructVBases = ctorType != Ctor_Base &&
257 classDecl->getNumVBases() != 0 &&
258 !classDecl->isAbstract();
259 if (constructVBases &&
260 !cgm.getTarget().getCXXABI().hasConstructorVariants()) {
261 cgm.errorNYI(cd->getSourceRange(),
262 "emitCtorPrologue: virtual base without variants");
263 return;
264 }
265
266 // Create three separate ranges for the different types of initializers.
267 auto allInits = cd->inits();
268
269 // Find the boundaries between the three groups.
270 auto virtualBaseEnd = std::find_if(
271 allInits.begin(), allInits.end(), [](const CXXCtorInitializer *Init) {
272 return !(Init->isBaseInitializer() && Init->isBaseVirtual());
273 });
274
275 auto nonVirtualBaseEnd = std::find_if(virtualBaseEnd, allInits.end(),
276 [](const CXXCtorInitializer *Init) {
277 return !Init->isBaseInitializer();
278 });
279
280 // Create the three ranges.
281 auto virtualBaseInits = llvm::make_range(allInits.begin(), virtualBaseEnd);
282 auto nonVirtualBaseInits =
283 llvm::make_range(virtualBaseEnd, nonVirtualBaseEnd);
284 auto memberInits = llvm::make_range(nonVirtualBaseEnd, allInits.end());
285
286 const mlir::Value oldThisValue = cxxThisValue;
287
288 auto emitInitializer = [&](CXXCtorInitializer *baseInit) {
289 if (cgm.getCodeGenOpts().StrictVTablePointers &&
290 cgm.getCodeGenOpts().OptimizationLevel > 0 &&
291 isInitializerOfDynamicClass(baseInit)) {
292 // It's OK to continue after emitting the error here. The missing code
293 // just "launders" the 'this' pointer.
294 cgm.errorNYI(cd->getSourceRange(),
295 "emitCtorPrologue: strict vtable pointers for vbase");
296 }
297 emitBaseInitializer(getLoc(cd->getBeginLoc()), classDecl, baseInit);
298 };
299
300 // Process virtual base initializers.
301 for (CXXCtorInitializer *virtualBaseInit : virtualBaseInits) {
302 if (!constructVBases)
303 continue;
304 emitInitializer(virtualBaseInit);
305 }
306
308
309 // Then, non-virtual base initializers.
310 for (CXXCtorInitializer *nonVirtualBaseInit : nonVirtualBaseInits) {
311 assert(!nonVirtualBaseInit->isBaseVirtual());
312 emitInitializer(nonVirtualBaseInit);
313 }
314
315 cxxThisValue = oldThisValue;
316
318
319 // Finally, initialize class members.
321 // Classic codegen uses a special class to attempt to replace member
322 // initializers with memcpy. We could possibly defer that to the
323 // lowering or optimization phases to keep the memory accesses more
324 // explicit. For now, we don't insert memcpy at all.
326 for (CXXCtorInitializer *member : memberInits) {
327 assert(!member->isBaseInitializer());
328 assert(member->isAnyMemberInitializer() &&
329 "Delegating initializer on non-delegating constructor");
330 emitMemberInitializer(*this, cd->getParent(), member, cd, args);
331 }
332}
333
335 mlir::Location loc, CIRGenFunction &cgf, Address addr,
336 CharUnits nonVirtualOffset, mlir::Value virtualOffset,
337 const CXXRecordDecl *derivedClass, const CXXRecordDecl *nearestVBase,
338 mlir::Type baseValueTy = {}, bool assumeNotNull = true) {
339 // Assert that we have something to do.
340 assert(!nonVirtualOffset.isZero() || virtualOffset != nullptr);
341
342 // Compute the offset from the static and dynamic components.
343 mlir::Value baseOffset;
344 if (!nonVirtualOffset.isZero()) {
345 if (virtualOffset) {
346 cgf.cgm.errorNYI(
347 loc,
348 "applyNonVirtualAndVirtualOffset: virtual and non-virtual offset");
349 return Address::invalid();
350 } else {
351 assert(baseValueTy && "expected base type");
352 // If no virtualOffset is present this is the final stop.
353 return cgf.getBuilder().createBaseClassAddr(
354 loc, addr, baseValueTy, nonVirtualOffset.getQuantity(),
355 assumeNotNull);
356 }
357 } else {
358 baseOffset = virtualOffset;
359 }
360
361 // Apply the base offset. cir.ptr_stride adjusts by a number of elements,
362 // not bytes. So the pointer must be cast to a byte pointer and back.
363
364 mlir::Value ptr = addr.getPointer();
365 mlir::Type charPtrType = cgf.cgm.UInt8PtrTy;
366 mlir::Value charPtr = cgf.getBuilder().createBitcast(ptr, charPtrType);
367 mlir::Value adjusted = cir::PtrStrideOp::create(
368 cgf.getBuilder(), loc, charPtrType, charPtr, baseOffset);
369 ptr = cgf.getBuilder().createBitcast(adjusted, ptr.getType());
370
371 // If we have a virtual component, the alignment of the result will
372 // be relative only to the known alignment of that vbase.
373 CharUnits alignment;
374 if (virtualOffset) {
375 assert(nearestVBase && "virtual offset without vbase?");
376 alignment = cgf.cgm.getVBaseAlignment(addr.getAlignment(), derivedClass,
377 nearestVBase);
378 } else {
379 alignment = addr.getAlignment();
380 }
381 alignment = alignment.alignmentAtOffset(nonVirtualOffset);
382
383 return Address(ptr, alignment);
384}
385
387 const VPtr &vptr) {
388 // Compute the address point.
389 mlir::Value vtableAddressPoint =
390 cgm.getCXXABI().getVTableAddressPointInStructor(
391 *this, vptr.vtableClass, vptr.base, vptr.nearestVBase);
392
393 if (!vtableAddressPoint)
394 return;
395
396 // Compute where to store the address point.
397 mlir::Value virtualOffset{};
398 CharUnits nonVirtualOffset = CharUnits::Zero();
399
400 mlir::Type baseValueTy;
401 if (cgm.getCXXABI().isVirtualOffsetNeededForVTableField(*this, vptr)) {
402 // We need to use the virtual base offset offset because the virtual base
403 // might have a different offset in the most derived class.
404 virtualOffset = cgm.getCXXABI().getVirtualBaseClassOffset(
405 loc, *this, loadCXXThisAddress(), vptr.vtableClass, vptr.nearestVBase);
406 nonVirtualOffset = vptr.offsetFromNearestVBase;
407 } else {
408 // We can just use the base offset in the complete class.
409 nonVirtualOffset = vptr.base.getBaseOffset();
410 baseValueTy =
411 convertType(getContext().getCanonicalTagType(vptr.base.getBase()));
412 }
413
414 // Apply the offsets.
415 Address classAddr = loadCXXThisAddress();
416 if (!nonVirtualOffset.isZero() || virtualOffset) {
418 loc, *this, classAddr, nonVirtualOffset, virtualOffset,
419 vptr.vtableClass, vptr.nearestVBase, baseValueTy);
420 }
421
422 // Finally, store the address point. Use the same CIR types as the field.
423 //
424 // vtable field is derived from `this` pointer, therefore they should be in
425 // the same addr space.
427 auto vtablePtr = cir::VTableGetVPtrOp::create(
428 builder, loc, builder.getPtrToVPtrType(), classAddr.getPointer());
429 Address vtableField = Address(vtablePtr, classAddr.getAlignment());
430 builder.createStore(loc, vtableAddressPoint, vtableField);
433}
434
436 const CXXRecordDecl *rd) {
437 // Ignore classes without a vtable.
438 if (!rd->isDynamicClass())
439 return;
440
441 // Initialize the vtable pointers for this class and all of its bases.
442 if (cgm.getCXXABI().doStructorsInitializeVPtrs(rd))
443 for (const auto &vptr : getVTablePointers(rd))
444 initializeVTablePointer(loc, vptr);
445
446 if (rd->getNumVBases())
447 cgm.getCXXABI().initializeHiddenVirtualInheritanceMembers(*this, rd);
448}
449
452 CIRGenFunction::VPtrsVector vptrsResult;
455 /*NearestVBase=*/nullptr,
456 /*OffsetFromNearestVBase=*/CharUnits::Zero(),
457 /*BaseIsNonVirtualPrimaryBase=*/false, vtableClass, vbases,
458 vptrsResult);
459 return vptrsResult;
460}
461
463 const CXXRecordDecl *nearestVBase,
464 CharUnits offsetFromNearestVBase,
465 bool baseIsNonVirtualPrimaryBase,
466 const CXXRecordDecl *vtableClass,
468 VPtrsVector &vptrs) {
469 // If this base is a non-virtual primary base the address point has already
470 // been set.
471 if (!baseIsNonVirtualPrimaryBase) {
472 // Initialize the vtable pointer for this base.
473 VPtr vptr = {base, nearestVBase, offsetFromNearestVBase, vtableClass};
474 vptrs.push_back(vptr);
475 }
476
477 const CXXRecordDecl *rd = base.getBase();
478
479 for (const auto &nextBase : rd->bases()) {
480 const auto *baseDecl =
482 nextBase.getType()->castAs<RecordType>()->getOriginalDecl())
483 ->getDefinitionOrSelf();
484
485 // Ignore classes without a vtable.
486 if (!baseDecl->isDynamicClass())
487 continue;
488
489 CharUnits baseOffset;
490 CharUnits baseOffsetFromNearestVBase;
491 bool baseDeclIsNonVirtualPrimaryBase;
492 const CXXRecordDecl *nextBaseDecl;
493
494 if (nextBase.isVirtual()) {
495 // Check if we've visited this virtual base before.
496 if (!vbases.insert(baseDecl).second)
497 continue;
498
499 const ASTRecordLayout &layout =
500 getContext().getASTRecordLayout(vtableClass);
501
502 nextBaseDecl = baseDecl;
503 baseOffset = layout.getVBaseClassOffset(baseDecl);
504 baseOffsetFromNearestVBase = CharUnits::Zero();
505 baseDeclIsNonVirtualPrimaryBase = false;
506 } else {
507 const ASTRecordLayout &layout = getContext().getASTRecordLayout(rd);
508
509 nextBaseDecl = nearestVBase;
510 baseOffset = base.getBaseOffset() + layout.getBaseClassOffset(baseDecl);
511 baseOffsetFromNearestVBase =
512 offsetFromNearestVBase + layout.getBaseClassOffset(baseDecl);
513 baseDeclIsNonVirtualPrimaryBase = layout.getPrimaryBase() == baseDecl;
514 }
515
516 getVTablePointers(BaseSubobject(baseDecl, baseOffset), nextBaseDecl,
517 baseOffsetFromNearestVBase,
518 baseDeclIsNonVirtualPrimaryBase, vtableClass, vbases,
519 vptrs);
520 }
521}
522
524 assert(curFuncDecl && "loading 'this' without a func declaration?");
526
527 // Lazily compute CXXThisAlignment.
528 if (cxxThisAlignment.isZero()) {
529 // Just use the best known alignment for the parent.
530 // TODO: if we're currently emitting a complete-object ctor/dtor, we can
531 // always use the complete-object alignment.
532 auto rd = cast<CXXMethodDecl>(curFuncDecl)->getParent();
533 cxxThisAlignment = cgm.getClassPointerAlignment(rd);
534 }
535
537}
538
540 Expr *init) {
541 QualType fieldType = field->getType();
542 switch (getEvaluationKind(fieldType)) {
543 case cir::TEK_Scalar:
544 if (lhs.isSimple()) {
545 emitExprAsInit(init, field, lhs, false);
546 } else {
547 RValue rhs = RValue::get(emitScalarExpr(init));
548 emitStoreThroughLValue(rhs, lhs);
549 }
550 break;
551 case cir::TEK_Complex:
552 emitComplexExprIntoLValue(init, lhs, /*isInit=*/true);
553 break;
554 case cir::TEK_Aggregate: {
560 emitAggExpr(init, slot);
561 break;
562 }
563 }
564
565 // Ensure that we destroy this object if an exception is thrown later in the
566 // constructor.
567 QualType::DestructionKind dtorKind = fieldType.isDestructedType();
568 (void)dtorKind;
570}
571
574 const CXXRecordDecl *baseDecl,
575 CharUnits expectedTargetAlign) {
576 // If the base is an incomplete type (which is, alas, possible with
577 // member pointers), be pessimistic.
578 if (!baseDecl->isCompleteDefinition())
579 return std::min(actualBaseAlign, expectedTargetAlign);
580
581 const ASTRecordLayout &baseLayout =
583 CharUnits expectedBaseAlign = baseLayout.getNonVirtualAlignment();
584
585 // If the class is properly aligned, assume the target offset is, too.
586 //
587 // This actually isn't necessarily the right thing to do --- if the
588 // class is a complete object, but it's only properly aligned for a
589 // base subobject, then the alignments of things relative to it are
590 // probably off as well. (Note that this requires the alignment of
591 // the target to be greater than the NV alignment of the derived
592 // class.)
593 //
594 // However, our approach to this kind of under-alignment can only
595 // ever be best effort; after all, we're never going to propagate
596 // alignments through variables or parameters. Note, in particular,
597 // that constructing a polymorphic type in an address that's less
598 // than pointer-aligned will generally trap in the constructor,
599 // unless we someday add some sort of attribute to change the
600 // assumed alignment of 'this'. So our goal here is pretty much
601 // just to allow the user to explicitly say that a pointer is
602 // under-aligned and then safely access its fields and vtables.
603 if (actualBaseAlign >= expectedBaseAlign)
604 return expectedTargetAlign;
605
606 // Otherwise, we might be offset by an arbitrary multiple of the
607 // actual alignment. The correct adjustment is to take the min of
608 // the two alignments.
609 return std::min(actualBaseAlign, expectedTargetAlign);
610}
611
612/// Return the best known alignment for a pointer to a virtual base,
613/// given the alignment of a pointer to the derived class.
616 const CXXRecordDecl *derivedClass,
617 const CXXRecordDecl *vbaseClass) {
618 // The basic idea here is that an underaligned derived pointer might
619 // indicate an underaligned base pointer.
620
621 assert(vbaseClass->isCompleteDefinition());
622 const ASTRecordLayout &baseLayout =
623 getASTContext().getASTRecordLayout(vbaseClass);
624 CharUnits expectedVBaseAlign = baseLayout.getNonVirtualAlignment();
625
626 return getDynamicOffsetAlignment(actualDerivedAlign, derivedClass,
627 expectedVBaseAlign);
628}
629
630/// Emit a loop to call a particular constructor for each of several members
631/// of an array.
632///
633/// \param ctor the constructor to call for each element
634/// \param arrayType the type of the array to initialize
635/// \param arrayBegin an arrayType*
636/// \param zeroInitialize true if each element should be
637/// zero-initialized before it is constructed
640 Address arrayBegin, const CXXConstructExpr *e, bool newPointerIsChecked,
641 bool zeroInitialize) {
642 QualType elementType;
643 mlir::Value numElements = emitArrayLength(arrayType, elementType, arrayBegin);
644 emitCXXAggrConstructorCall(ctor, numElements, arrayBegin, e,
645 newPointerIsChecked, zeroInitialize);
646}
647
648/// Emit a loop to call a particular constructor for each of several members
649/// of an array.
650///
651/// \param ctor the constructor to call for each element
652/// \param numElements the number of elements in the array;
653/// may be zero
654/// \param arrayBase a T*, where T is the type constructed by ctor
655/// \param zeroInitialize true if each element should be
656/// zero-initialized before it is constructed
658 const CXXConstructorDecl *ctor, mlir::Value numElements, Address arrayBase,
659 const CXXConstructExpr *e, bool newPointerIsChecked, bool zeroInitialize) {
660 // It's legal for numElements to be zero. This can happen both
661 // dynamically, because x can be zero in 'new A[x]', and statically,
662 // because of GCC extensions that permit zero-length arrays. There
663 // are probably legitimate places where we could assume that this
664 // doesn't happen, but it's not clear that it's worth it.
665
666 auto arrayTy = mlir::cast<cir::ArrayType>(arrayBase.getElementType());
667 mlir::Type elementType = arrayTy.getElementType();
668
669 // This might be a multi-dimensional array. Find the innermost element type.
670 while (auto maybeArrayTy = mlir::dyn_cast<cir::ArrayType>(elementType))
671 elementType = maybeArrayTy.getElementType();
672 cir::PointerType ptrToElmType = builder.getPointerTo(elementType);
673
674 // Optimize for a constant count.
675 if (auto constantCount = numElements.getDefiningOp<cir::ConstantOp>()) {
676 if (auto constIntAttr = constantCount.getValueAttr<cir::IntAttr>()) {
677 // Just skip out if the constant count is zero.
678 if (constIntAttr.getUInt() == 0)
679 return;
680
681 arrayTy = cir::ArrayType::get(elementType, constIntAttr.getUInt());
682 // Otherwise, emit the check.
683 }
684
685 if (constantCount.use_empty())
686 constantCount.erase();
687 } else {
688 // Otherwise, emit the check.
689 cgm.errorNYI(e->getSourceRange(), "dynamic-length array expression");
690 }
691
692 // Tradional LLVM codegen emits a loop here. CIR lowers to a loop as part of
693 // LoweringPrepare.
694
695 // The alignment of the base, adjusted by the size of a single element,
696 // provides a conservative estimate of the alignment of every element.
697 // (This assumes we never start tracking offsetted alignments.)
698 //
699 // Note that these are complete objects and so we don't need to
700 // use the non-virtual size or alignment.
702 CharUnits eltAlignment = arrayBase.getAlignment().alignmentOfArrayElement(
703 getContext().getTypeSizeInChars(type));
704
705 // Zero initialize the storage, if requested.
706 if (zeroInitialize)
708
709 // C++ [class.temporary]p4:
710 // There are two contexts in which temporaries are destroyed at a different
711 // point than the end of the full-expression. The first context is when a
712 // default constructor is called to initialize an element of an array.
713 // If the constructor has one or more default arguments, the destruction of
714 // every temporary created in a default argument expression is sequenced
715 // before the construction of the next array element, if any.
716 {
717 RunCleanupsScope scope(*this);
718
719 // Evaluate the constructor and its arguments in a regular
720 // partial-destroy cleanup.
721 if (getLangOpts().Exceptions &&
722 !ctor->getParent()->hasTrivialDestructor()) {
723 cgm.errorNYI(e->getSourceRange(), "partial array cleanups");
724 }
725
726 // Emit the constructor call that will execute for every array element.
727 mlir::Value arrayOp =
728 builder.createPtrBitcast(arrayBase.getPointer(), arrayTy);
729 builder.create<cir::ArrayCtor>(
730 *currSrcLoc, arrayOp, [&](mlir::OpBuilder &b, mlir::Location loc) {
731 mlir::BlockArgument arg =
732 b.getInsertionBlock()->addArgument(ptrToElmType, loc);
733 Address curAddr = Address(arg, elementType, eltAlignment);
735 auto currAVS = AggValueSlot::forAddr(
736 curAddr, type.getQualifiers(), AggValueSlot::IsDestructed,
740 /*ForVirtualBase=*/false,
741 /*Delegating=*/false, currAVS, e);
742 builder.create<cir::YieldOp>(loc);
743 });
744 }
745}
746
748 const CXXConstructorDecl *ctor, CXXCtorType ctorType,
749 const FunctionArgList &args, SourceLocation loc) {
750 CallArgList delegateArgs;
751
752 FunctionArgList::const_iterator i = args.begin(), e = args.end();
753 assert(i != e && "no parameters to constructor");
754
755 // this
756 Address thisAddr = loadCXXThisAddress();
757 delegateArgs.add(RValue::get(thisAddr.getPointer()), (*i)->getType());
758 ++i;
759
760 // FIXME: The location of the VTT parameter in the parameter list is specific
761 // to the Itanium ABI and shouldn't be hardcoded here.
762 if (cgm.getCXXABI().needsVTTParameter(curGD)) {
763 cgm.errorNYI(loc, "emitDelegateCXXConstructorCall: VTT parameter");
764 return;
765 }
766
767 // Explicit arguments.
768 for (; i != e; ++i) {
769 const VarDecl *param = *i;
770 // FIXME: per-argument source location
771 emitDelegateCallArg(delegateArgs, param, loc);
772 }
773
775
776 emitCXXConstructorCall(ctor, ctorType, /*ForVirtualBase=*/false,
777 /*Delegating=*/true, thisAddr, delegateArgs, loc);
778}
779
781 const auto *assignOp = cast<CXXMethodDecl>(curGD.getDecl());
782 assert(assignOp->isCopyAssignmentOperator() ||
783 assignOp->isMoveAssignmentOperator());
784 const Stmt *rootS = assignOp->getBody();
785 assert(isa<CompoundStmt>(rootS) &&
786 "Body of an implicit assignment operator should be compound stmt.");
787 const auto *rootCS = cast<CompoundStmt>(rootS);
788
791
792 // Classic codegen uses a special class to attempt to replace member
793 // initializers with memcpy. We could possibly defer that to the
794 // lowering or optimization phases to keep the memory accesses more
795 // explicit. For now, we don't insert memcpy at all, though in some
796 // cases the AST contains a call to memcpy.
798 for (Stmt *s : rootCS->body())
799 if (emitStmt(s, /*useCurrentScope=*/true).failed())
800 cgm.errorNYI(s->getSourceRange(),
801 std::string("emitImplicitAssignmentOperatorBody: ") +
802 s->getStmtClassName());
803}
804
806 const CXXMethodDecl *callOperator, CallArgList &callArgs) {
807 // Get the address of the call operator.
808 const CIRGenFunctionInfo &calleeFnInfo =
809 cgm.getTypes().arrangeCXXMethodDeclaration(callOperator);
810 cir::FuncOp calleePtr = cgm.getAddrOfFunction(
811 GlobalDecl(callOperator), cgm.getTypes().getFunctionType(calleeFnInfo));
812
813 // Prepare the return slot.
814 const FunctionProtoType *fpt =
815 callOperator->getType()->castAs<FunctionProtoType>();
816 QualType resultType = fpt->getReturnType();
817 ReturnValueSlot returnSlot;
818
819 // We don't need to separately arrange the call arguments because
820 // the call can't be variadic anyway --- it's impossible to forward
821 // variadic arguments.
822
823 // Now emit our call.
824 CIRGenCallee callee =
825 CIRGenCallee::forDirect(calleePtr, GlobalDecl(callOperator));
826 RValue rv = emitCall(calleeFnInfo, callee, returnSlot, callArgs);
827
828 // If necessary, copy the returned value into the slot.
829 if (!resultType->isVoidType() && returnSlot.isNull()) {
830 if (getLangOpts().ObjCAutoRefCount && resultType->isObjCRetainableType())
831 cgm.errorNYI(callOperator->getSourceRange(),
832 "emitForwardingCallToLambda: ObjCAutoRefCount");
833 emitReturnOfRValue(*currSrcLoc, rv, resultType);
834 } else {
835 cgm.errorNYI(callOperator->getSourceRange(),
836 "emitForwardingCallToLambda: return slot is not null");
837 }
838}
839
841 const CXXRecordDecl *lambda = md->getParent();
842
843 // Start building arguments for forwarding call
844 CallArgList callArgs;
845
846 QualType lambdaType = getContext().getCanonicalTagType(lambda);
847 QualType thisType = getContext().getPointerType(lambdaType);
848 Address thisPtr =
849 createMemTemp(lambdaType, getLoc(md->getSourceRange()), "unused.capture");
850 callArgs.add(RValue::get(thisPtr.getPointer()), thisType);
851
852 // Add the rest of the parameters.
853 for (auto *param : md->parameters())
854 emitDelegateCallArg(callArgs, param, param->getBeginLoc());
855
856 const CXXMethodDecl *callOp = lambda->getLambdaCallOperator();
857 // For a generic lambda, find the corresponding call operator specialization
858 // to which the call to the static-invoker shall be forwarded.
859 if (lambda->isGenericLambda()) {
862 FunctionTemplateDecl *callOpTemplate =
864 void *InsertPos = nullptr;
865 FunctionDecl *correspondingCallOpSpecialization =
866 callOpTemplate->findSpecialization(tal->asArray(), InsertPos);
867 assert(correspondingCallOpSpecialization);
868 callOp = cast<CXXMethodDecl>(correspondingCallOpSpecialization);
869 }
870 emitForwardingCallToLambda(callOp, callArgs);
871}
872
874 if (md->isVariadic()) {
875 // Codgen for LLVM doesn't emit code for this as well, it says:
876 // FIXME: Making this work correctly is nasty because it requires either
877 // cloning the body of the call operator or making the call operator
878 // forward.
879 cgm.errorNYI(md->getSourceRange(), "emitLambdaStaticInvokeBody: variadic");
880 }
881
883}
884
886 QualType type) {
887 const auto *record = type->castAsCXXRecordDecl();
888 const CXXDestructorDecl *dtor = record->getDestructor();
889 // TODO(cir): Unlike traditional codegen, CIRGen should actually emit trivial
890 // dtors which shall be removed on later CIR passes. However, only remove this
891 // assertion after we have a test case to exercise this path.
892 assert(!dtor->isTrivial());
893 cgf.emitCXXDestructorCall(dtor, Dtor_Complete, /*forVirtualBase*/ false,
894 /*delegating=*/false, addr, type);
895}
896
897namespace {
898mlir::Value loadThisForDtorDelete(CIRGenFunction &cgf,
899 const CXXDestructorDecl *dd) {
900 if (Expr *thisArg = dd->getOperatorDeleteThisArg())
901 return cgf.emitScalarExpr(thisArg);
902 return cgf.loadCXXThis();
903}
904
905/// Call the operator delete associated with the current destructor.
906struct CallDtorDelete final : EHScopeStack::Cleanup {
907 CallDtorDelete() {}
908
909 void emit(CIRGenFunction &cgf) override {
910 const CXXDestructorDecl *dtor = cast<CXXDestructorDecl>(cgf.curFuncDecl);
911 const CXXRecordDecl *classDecl = dtor->getParent();
913 loadThisForDtorDelete(cgf, dtor),
914 cgf.getContext().getCanonicalTagType(classDecl));
915 }
916};
917
918class DestroyField final : public EHScopeStack::Cleanup {
919 const FieldDecl *field;
920 CIRGenFunction::Destroyer *destroyer;
921
922public:
923 DestroyField(const FieldDecl *field, CIRGenFunction::Destroyer *destroyer)
924 : field(field), destroyer(destroyer) {}
925
926 void emit(CIRGenFunction &cgf) override {
927 // Find the address of the field.
928 Address thisValue = cgf.loadCXXThisAddress();
929 CanQualType recordTy =
930 cgf.getContext().getCanonicalTagType(field->getParent());
931 LValue thisLV = cgf.makeAddrLValue(thisValue, recordTy);
932 LValue lv = cgf.emitLValueForField(thisLV, field);
933 assert(lv.isSimple());
934
936 cgf.emitDestroy(lv.getAddress(), field->getType(), destroyer);
937 }
938};
939} // namespace
940
941/// Emit all code that comes at the end of class's destructor. This is to call
942/// destructors on members and base classes in reverse order of their
943/// construction.
944///
945/// For a deleting destructor, this also handles the case where a destroying
946/// operator delete completely overrides the definition.
948 CXXDtorType dtorType) {
949 assert((!dd->isTrivial() || dd->hasAttr<DLLExportAttr>()) &&
950 "Should not emit dtor epilogue for non-exported trivial dtor!");
951
952 // The deleting-destructor phase just needs to call the appropriate
953 // operator delete that Sema picked up.
954 if (dtorType == Dtor_Deleting) {
955 assert(dd->getOperatorDelete() &&
956 "operator delete missing - EnterDtorCleanups");
958 cgm.errorNYI(dd->getSourceRange(), "deleting destructor with vtt");
959 } else {
961 cgm.errorNYI(dd->getSourceRange(),
962 "deleting destructor with destroying operator delete");
963 } else {
964 ehStack.pushCleanup<CallDtorDelete>(NormalAndEHCleanup);
965 }
966 }
967 return;
968 }
969
970 const CXXRecordDecl *classDecl = dd->getParent();
971
972 // Unions have no bases and do not call field destructors.
973 if (classDecl->isUnion())
974 return;
975
976 // The complete-destructor phase just destructs all the virtual bases.
977 if (dtorType == Dtor_Complete) {
979
980 // We push them in the forward order so that they'll be popped in
981 // the reverse order.
982 for (const CXXBaseSpecifier &base : classDecl->vbases()) {
983 auto *baseClassDecl = base.getType()->castAsCXXRecordDecl();
984
985 if (baseClassDecl->hasTrivialDestructor()) {
986 // Under SanitizeMemoryUseAfterDtor, poison the trivial base class
987 // memory. For non-trival base classes the same is done in the class
988 // destructor.
990 } else {
991 ehStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, baseClassDecl,
992 /*baseIsVirtual=*/true);
993 }
994 }
995
996 return;
997 }
998
999 assert(dtorType == Dtor_Base);
1001
1002 // Destroy non-virtual bases.
1003 for (const CXXBaseSpecifier &base : classDecl->bases()) {
1004 // Ignore virtual bases.
1005 if (base.isVirtual())
1006 continue;
1007
1008 CXXRecordDecl *baseClassDecl = base.getType()->getAsCXXRecordDecl();
1009
1010 if (baseClassDecl->hasTrivialDestructor())
1012 else
1013 ehStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, baseClassDecl,
1014 /*baseIsVirtual=*/false);
1015 }
1016
1018
1019 // Destroy direct fields.
1020 for (const FieldDecl *field : classDecl->fields()) {
1021 QualType type = field->getType();
1022 QualType::DestructionKind dtorKind = type.isDestructedType();
1023 if (!dtorKind)
1024 continue;
1025
1026 // Anonymous union members do not have their destructors called.
1027 const RecordType *rt = type->getAsUnionType();
1028 if (rt && rt->getOriginalDecl()->isAnonymousStructOrUnion())
1029 continue;
1030
1031 CleanupKind cleanupKind = getCleanupKind(dtorKind);
1033 ehStack.pushCleanup<DestroyField>(cleanupKind, field,
1034 getDestroyer(dtorKind));
1035 }
1036}
1037
1039 const CXXConstructorDecl *ctor, const FunctionArgList &args) {
1040 assert(ctor->isDelegatingConstructor());
1041
1042 Address thisPtr = loadCXXThisAddress();
1043
1050
1051 emitAggExpr(ctor->init_begin()[0]->getInit(), aggSlot);
1052
1053 const CXXRecordDecl *classDecl = ctor->getParent();
1054 if (cgm.getLangOpts().Exceptions && !classDecl->hasTrivialDestructor()) {
1055 cgm.errorNYI(ctor->getSourceRange(),
1056 "emitDelegatingCXXConstructorCall: exception");
1057 return;
1058 }
1059}
1060
1063 bool forVirtualBase, bool delegating,
1064 Address thisAddr, QualType thisTy) {
1065 cgm.getCXXABI().emitDestructorCall(*this, dd, type, forVirtualBase,
1066 delegating, thisAddr, thisTy);
1067}
1068
1069mlir::Value CIRGenFunction::getVTTParameter(GlobalDecl gd, bool forVirtualBase,
1070 bool delegating) {
1071 if (!cgm.getCXXABI().needsVTTParameter(gd))
1072 return nullptr;
1073
1074 const CXXRecordDecl *rd = cast<CXXMethodDecl>(curCodeDecl)->getParent();
1075 const CXXRecordDecl *base = cast<CXXMethodDecl>(gd.getDecl())->getParent();
1076
1077 uint64_t subVTTIndex;
1078
1079 if (delegating) {
1080 // If this is a delegating constructor call, just load the VTT.
1081 return loadCXXVTT();
1082 } else if (rd == base) {
1083 // If the record matches the base, this is the complete ctor/dtor
1084 // variant calling the base variant in a class with virtual bases.
1085 assert(!cgm.getCXXABI().needsVTTParameter(curGD) &&
1086 "doing no-op VTT offset in base dtor/ctor?");
1087 assert(!forVirtualBase && "Can't have same class as virtual base!");
1088 subVTTIndex = 0;
1089 } else {
1090 const ASTRecordLayout &layout = getContext().getASTRecordLayout(rd);
1091 CharUnits baseOffset = forVirtualBase ? layout.getVBaseClassOffset(base)
1092 : layout.getBaseClassOffset(base);
1093
1094 subVTTIndex =
1095 cgm.getVTables().getSubVTTIndex(rd, BaseSubobject(base, baseOffset));
1096 assert(subVTTIndex != 0 && "Sub-VTT index must be greater than zero!");
1097 }
1098
1099 mlir::Location loc = cgm.getLoc(rd->getBeginLoc());
1100 if (cgm.getCXXABI().needsVTTParameter(curGD)) {
1101 // A VTT parameter was passed to the constructor, use it.
1102 mlir::Value vtt = loadCXXVTT();
1103 return builder.createVTTAddrPoint(loc, vtt.getType(), vtt, subVTTIndex);
1104 } else {
1105 // We're the complete constructor, so get the VTT by name.
1106 cir::GlobalOp vtt = cgm.getVTables().getAddrOfVTT(rd);
1107 return builder.createVTTAddrPoint(
1108 loc, builder.getPointerTo(cgm.VoidPtrTy),
1109 mlir::FlatSymbolRefAttr::get(vtt.getSymNameAttr()), subVTTIndex);
1110 }
1111}
1112
1114 Address value, const CXXRecordDecl *derived,
1115 llvm::iterator_range<CastExpr::path_const_iterator> path,
1116 bool nullCheckValue, SourceLocation loc) {
1117 assert(!path.empty() && "Base path should not be empty!");
1118
1119 CastExpr::path_const_iterator start = path.begin();
1120 const CXXRecordDecl *vBase = nullptr;
1121
1122 if ((*path.begin())->isVirtual()) {
1123 vBase = (*start)->getType()->castAsCXXRecordDecl();
1124 ++start;
1125 }
1126
1127 // Compute the static offset of the ultimate destination within its
1128 // allocating subobject (the virtual base, if there is one, or else
1129 // the "complete" object that we see).
1130 CharUnits nonVirtualOffset = cgm.computeNonVirtualBaseClassOffset(
1131 vBase ? vBase : derived, {start, path.end()});
1132
1133 // If there's a virtual step, we can sometimes "devirtualize" it.
1134 // For now, that's limited to when the derived type is final.
1135 // TODO: "devirtualize" this for accesses to known-complete objects.
1136 if (vBase && derived->hasAttr<FinalAttr>()) {
1137 const ASTRecordLayout &layout = getContext().getASTRecordLayout(derived);
1138 CharUnits vBaseOffset = layout.getVBaseClassOffset(vBase);
1139 nonVirtualOffset += vBaseOffset;
1140 vBase = nullptr; // we no longer have a virtual step
1141 }
1142
1143 // Get the base pointer type.
1144 mlir::Type baseValueTy = convertType((path.end()[-1])->getType());
1146
1147 // If there is no virtual base, use cir.base_class_addr. It takes care of
1148 // the adjustment and the null pointer check.
1149 if (nonVirtualOffset.isZero() && !vBase) {
1151 return builder.createBaseClassAddr(getLoc(loc), value, baseValueTy, 0,
1152 /*assumeNotNull=*/true);
1153 }
1154
1156
1157 // Compute the virtual offset.
1158 mlir::Value virtualOffset = nullptr;
1159 if (vBase) {
1160 virtualOffset = cgm.getCXXABI().getVirtualBaseClassOffset(
1161 getLoc(loc), *this, value, derived, vBase);
1162 }
1163
1164 // Apply both offsets.
1166 getLoc(loc), *this, value, nonVirtualOffset, virtualOffset, derived,
1167 vBase, baseValueTy, not nullCheckValue);
1168
1169 // Cast to the destination type.
1170 value = value.withElementType(builder, baseValueTy);
1171
1172 return value;
1173}
1174
1175// TODO(cir): this can be shared with LLVM codegen.
1178 if (!cgm.getCodeGenOpts().WholeProgramVTables)
1179 return false;
1180
1181 if (cgm.getCodeGenOpts().VirtualFunctionElimination)
1182 return true;
1183
1185
1186 return false;
1187}
1188
1189mlir::Value CIRGenFunction::getVTablePtr(mlir::Location loc, Address thisAddr,
1190 const CXXRecordDecl *rd) {
1191 auto vtablePtr = cir::VTableGetVPtrOp::create(
1192 builder, loc, builder.getPtrToVPtrType(), thisAddr.getPointer());
1193 Address vtablePtrAddr = Address(vtablePtr, thisAddr.getAlignment());
1194
1195 auto vtable = builder.createLoad(loc, vtablePtrAddr);
1197
1198 if (cgm.getCodeGenOpts().OptimizationLevel > 0 &&
1199 cgm.getCodeGenOpts().StrictVTablePointers) {
1201 }
1202
1203 return vtable;
1204}
1205
1208 bool forVirtualBase,
1209 bool delegating,
1210 AggValueSlot thisAVS,
1211 const clang::CXXConstructExpr *e) {
1212 CallArgList args;
1213 Address thisAddr = thisAVS.getAddress();
1214 QualType thisType = d->getThisType();
1215 mlir::Value thisPtr = thisAddr.getPointer();
1216
1218
1219 args.add(RValue::get(thisPtr), thisType);
1220
1221 // In LLVM Codegen: If this is a trivial constructor, just emit what's needed.
1222 // If this is a union copy constructor, we must emit a memcpy, because the AST
1223 // does not model that copy.
1225
1226 const FunctionProtoType *fpt = d->getType()->castAs<FunctionProtoType>();
1227
1229
1230 emitCallArgs(args, fpt, e->arguments(), e->getConstructor(),
1231 /*ParamsToSkip=*/0);
1232
1234 emitCXXConstructorCall(d, type, forVirtualBase, delegating, thisAddr, args,
1235 e->getExprLoc());
1236}
1237
1239 const CXXConstructorDecl *d, CXXCtorType type, bool forVirtualBase,
1240 bool delegating, Address thisAddr, CallArgList &args, SourceLocation loc) {
1241
1242 const CXXRecordDecl *crd = d->getParent();
1243
1244 // If this is a call to a trivial default constructor:
1245 // In LLVM: do nothing.
1246 // In CIR: emit as a regular call, other later passes should lower the
1247 // ctor call into trivial initialization.
1249
1251
1252 bool passPrototypeArgs = true;
1253
1254 // Check whether we can actually emit the constructor before trying to do so.
1255 if (d->getInheritedConstructor()) {
1256 cgm.errorNYI(d->getSourceRange(),
1257 "emitCXXConstructorCall: inherited constructor");
1258 return;
1259 }
1260
1261 // Insert any ABI-specific implicit constructor arguments.
1263 cgm.getCXXABI().addImplicitConstructorArgs(*this, d, type, forVirtualBase,
1264 delegating, args);
1265
1266 // Emit the call.
1267 auto calleePtr = cgm.getAddrOfCXXStructor(GlobalDecl(d, type));
1268 const CIRGenFunctionInfo &info = cgm.getTypes().arrangeCXXConstructorCall(
1269 args, d, type, extraArgs.prefix, extraArgs.suffix, passPrototypeArgs);
1270 CIRGenCallee callee = CIRGenCallee::forDirect(calleePtr, GlobalDecl(d, type));
1271 cir::CIRCallOpInterface c;
1272 emitCall(info, callee, ReturnValueSlot(), args, &c, getLoc(loc));
1273
1274 if (cgm.getCodeGenOpts().OptimizationLevel != 0 && !crd->isDynamicClass() &&
1275 type != Ctor_Base && cgm.getCodeGenOpts().StrictVTablePointers)
1276 cgm.errorNYI(d->getSourceRange(), "vtable assumption loads");
1277}
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 bool baseInitializerUsesThis(ASTContext &c, const Expr *init)
static Address applyNonVirtualAndVirtualOffset(mlir::Location loc, CIRGenFunction &cgf, Address addr, CharUnits nonVirtualOffset, mlir::Value virtualOffset, const CXXRecordDecl *derivedClass, const CXXRecordDecl *nearestVBase, mlir::Type baseValueTy={}, bool assumeNotNull=true)
static void emitMemberInitializer(CIRGenFunction &cgf, const CXXRecordDecl *classDecl, CXXCtorInitializer *memberInit, const CXXConstructorDecl *constructor, FunctionArgList &args)
static bool isInitializerOfDynamicClass(const CXXCtorInitializer *baseInit)
static void emitLValueForAnyFieldInitialization(CIRGenFunction &cgf, CXXCtorInitializer *memberInit, LValue &lhs)
Defines the clang::Expr interface and subclasses for C++ expressions.
C Language Family Type Representation.
__device__ __2f16 b
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
mlir::Value createBitcast(mlir::Value src, mlir::Type newTy)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:220
const ConstantArrayType * getAsConstantArrayType(QualType T) const
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
CanQualType getCanonicalTagType(const TagDecl *TD) const
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getNonVirtualAlignment() const
getNonVirtualAlignment - Get the non-virtual alignment (in chars) of an object, which is the alignmen...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition TypeBase.h:3722
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
mlir::Value getPointer() const
Definition Address.h:82
mlir::Type getElementType() const
Definition Address.h:109
static Address invalid()
Definition Address.h:67
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:117
An aggregate value slot.
static AggValueSlot forAddr(Address addr, clang::Qualifiers quals, IsDestructed_t isDestructed, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed)
static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed)
Address createBaseClassAddr(mlir::Location loc, Address addr, mlir::Type destType, unsigned offset, bool assumeNotNull)
static CIRGenCallee forDirect(mlir::Operation *funcPtr, const CIRGenCalleeInfo &abstractInfo=CIRGenCalleeInfo())
Definition CIRGenCall.h:90
A scope within which we are constructing the fields of an object which might use a CXXDefaultInitExpr...
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
static bool isConstructorDelegationValid(const clang::CXXConstructorDecl *ctor)
Checks whether the given constructor is a valid subject for the complete-to-base constructor delegati...
void emitLambdaDelegatingInvokeBody(const CXXMethodDecl *md)
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...
const clang::LangOptions & getLangOpts() const
void emitForwardingCallToLambda(const CXXMethodDecl *lambdaCallOperator, CallArgList &callArgs)
mlir::Value loadCXXThis()
Load the value for 'this'.
LValue makeNaturalAlignPointeeAddrLValue(mlir::Value v, clang::QualType t)
Given a value of type T* that may not be to a complete object, construct an l-vlaue withi the natural...
void emitDeleteCall(const FunctionDecl *deleteFD, mlir::Value ptr, QualType deleteTy)
clang::CharUnits cxxThisAlignment
const clang::Decl * curFuncDecl
LValue makeNaturalAlignAddrLValue(mlir::Value val, QualType ty)
mlir::Value getVTTParameter(GlobalDecl gd, bool forVirtualBase, bool delegating)
Return the VTT parameter that should be passed to a base constructor/destructor with virtual bases.
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
void initializeVTablePointers(mlir::Location loc, const clang::CXXRecordDecl *rd)
void initializeVTablePointer(mlir::Location loc, const VPtr &vptr)
Address getAddressOfBaseClass(Address value, const CXXRecordDecl *derived, llvm::iterator_range< CastExpr::path_const_iterator > path, bool nullCheckValue, SourceLocation loc)
void emitDelegateCXXConstructorCall(const clang::CXXConstructorDecl *ctor, clang::CXXCtorType ctorType, const FunctionArgList &args, clang::SourceLocation loc)
void emitBaseInitializer(mlir::Location loc, const CXXRecordDecl *classDecl, CXXCtorInitializer *baseInit)
void emitExprAsInit(const clang::Expr *init, const clang::ValueDecl *d, LValue lvalue, bool capturedByInit=false)
Emit an expression as an initializer for an object (variable, field, etc.) at the given location.
mlir::Value emitArrayLength(const clang::ArrayType *arrayType, QualType &baseType, Address &addr)
Computes the length of an array in elements, as well as the base element type and a properly-typed fi...
void emitNullInitialization(mlir::Location loc, Address destPtr, QualType ty)
VPtrsVector getVTablePointers(const clang::CXXRecordDecl *vtableClass)
CleanupKind getCleanupKind(QualType::DestructionKind kind)
AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *fd)
EHScopeStack ehStack
Tracks function scope overall cleanup handling.
void enterDtorCleanups(const CXXDestructorDecl *dtor, CXXDtorType type)
Enter the cleanups necessary to complete the given phase of destruction for a destructor.
void emitImplicitAssignmentOperatorBody(FunctionArgList &args)
void emitCtorPrologue(const clang::CXXConstructorDecl *ctor, clang::CXXCtorType ctorType, FunctionArgList &args)
This routine generates necessary code to initialize base classes and non-static data members belongin...
mlir::Value loadCXXVTT()
Load the VTT parameter to base constructors/destructors have virtual bases.
void emitCXXConstructorCall(const clang::CXXConstructorDecl *d, clang::CXXCtorType type, bool forVirtualBase, bool delegating, AggValueSlot thisAVS, const clang::CXXConstructExpr *e)
mlir::Value getVTablePtr(mlir::Location loc, Address thisAddr, const clang::CXXRecordDecl *vtableClass)
Return the Value of the vtable pointer member pointed to by thisAddr.
llvm::SmallPtrSet< const clang::CXXRecordDecl *, 4 > VisitedVirtualBasesSetTy
void emitReturnOfRValue(mlir::Location loc, RValue rv, QualType ty)
bool shouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *rd)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
RValue emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, const CallArgList &args, cir::CIRCallOpInterface *callOp, mlir::Location loc)
const clang::Decl * curCodeDecl
This is the inner-most code context, which includes blocks.
LValue emitLValueForFieldInitialization(LValue base, const clang::FieldDecl *field, llvm::StringRef fieldName)
Like emitLValueForField, excpet that if the Field is a reference, this will return the address of the...
mlir::Value emitScalarExpr(const clang::Expr *e)
Emit the computation of the specified expression of scalar type.
void emitInitializerForField(clang::FieldDecl *field, LValue lhs, clang::Expr *init)
LValue emitLValueForField(LValue base, const clang::FieldDecl *field)
Address getAddressOfDirectBaseInCompleteClass(mlir::Location loc, Address value, const CXXRecordDecl *derived, const CXXRecordDecl *base, bool baseIsVirtual)
Convert the given pointer to a complete class to the given direct base.
CIRGenBuilderTy & getBuilder()
AggValueSlot::Overlap_t getOverlapForBaseInit(const CXXRecordDecl *rd, const CXXRecordDecl *baseRD, bool isVirtual)
Determine whether a base class initialization may overlap some other object.
void emitDestroy(Address addr, QualType type, Destroyer *destroyer)
Immediately perform the destruction of the given object.
Destroyer * getDestroyer(clang::QualType::DestructionKind kind)
void Destroyer(CIRGenFunction &cgf, Address addr, QualType ty)
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)
llvm::SmallVector< VPtr, 4 > VPtrsVector
void emitLambdaStaticInvokeBody(const CXXMethodDecl *md)
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.
void emitDelegateCallArg(CallArgList &args, const clang::VarDecl *param, clang::SourceLocation loc)
We are performing a delegate call; that is, the current function is delegating to another one.
std::optional< mlir::Location > currSrcLoc
Use to track source locations across nested visitor traversals.
clang::ASTContext & getContext() const
void emitStoreThroughLValue(RValue src, LValue dst, bool isInit=false)
Store the specified rvalue into the specified lvalue, where both are guaranteed to the have the same ...
mlir::LogicalResult emitStmt(const clang::Stmt *s, bool useCurrentScope, llvm::ArrayRef< const Attr * > attrs={})
Address createMemTemp(QualType t, mlir::Location loc, const Twine &name="tmp", Address *alloca=nullptr, mlir::OpBuilder::InsertPoint ip={})
Create a temporary memory object of the given type, with appropriate alignmen and cast it to the defa...
void emitDelegatingCXXConstructorCall(const CXXConstructorDecl *ctor, const FunctionArgList &args)
void emitAggExpr(const clang::Expr *e, AggValueSlot slot)
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
clang::ASTContext & getASTContext() const
CharUnits getDynamicOffsetAlignment(CharUnits actualBaseAlign, const CXXRecordDecl *baseDecl, CharUnits expectedTargetAlign)
TODO: Add TBAAAccessInfo.
CharUnits getVBaseAlignment(CharUnits derivedAlign, const CXXRecordDecl *derived, const CXXRecordDecl *vbase)
Returns the assumed alignment of a virtual base of a class.
void add(RValue rvalue, clang::QualType type)
Definition CIRGenCall.h:233
Information for lazily generating a cleanup.
Type for representing both the decl and type of parameters to a function.
Definition CIRGenCall.h:191
bool isSimple() const
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:82
Contains the address where the return value of a function can be stored, and whether the address is v...
Definition CIRGenCall.h:254
Represents a base class of a C++ class.
Definition DeclCXX.h:146
Represents a call to a C++ constructor.
Definition ExprCXX.h:1549
arg_range arguments()
Definition ExprCXX.h:1673
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition ExprCXX.h:1612
Represents a C++ constructor within a class.
Definition DeclCXX.h:2604
init_iterator init_begin()
Retrieve an iterator to the first initializer.
Definition DeclCXX.h:2701
bool isDelegatingConstructor() const
Determine whether this constructor is a delegating constructor.
Definition DeclCXX.h:2757
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
Definition DeclCXX.cpp:3019
InheritedConstructor getInheritedConstructor() const
Get the constructor that this inheriting constructor is based on.
Definition DeclCXX.h:2842
Represents a C++ base or member initializer.
Definition DeclCXX.h:2369
Expr * getInit() const
Get the initializer.
Definition DeclCXX.h:2571
SourceRange getSourceRange() const LLVM_READONLY
Determine the source range covering the entire initializer.
Definition DeclCXX.cpp:2916
bool isAnyMemberInitializer() const
Definition DeclCXX.h:2449
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
Definition DeclCXX.h:2441
bool isIndirectMemberInitializer() const
Definition DeclCXX.h:2453
const Type * getBaseClass() const
If this is a base class initializer, returns the type of the base class.
Definition DeclCXX.cpp:2896
FieldDecl * getAnyMember() const
Definition DeclCXX.h:2515
IndirectFieldDecl * getIndirectMember() const
Definition DeclCXX.h:2523
bool isBaseVirtual() const
Returns whether the base is virtual or not.
Definition DeclCXX.h:2495
Represents a C++ destructor within a class.
Definition DeclCXX.h:2869
const FunctionDecl * getOperatorDelete() const
Definition DeclCXX.h:2904
Expr * getOperatorDeleteThisArg() const
Definition DeclCXX.h:2912
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2129
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition DeclCXX.h:2255
QualType getThisType() const
Return the type of the this pointer.
Definition DeclCXX.cpp:2809
QualType getFunctionObjectParameterType() const
Definition DeclCXX.h:2279
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
Definition DeclCXX.cpp:1673
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
Definition DeclCXX.h:1366
base_class_range bases()
Definition DeclCXX.h:608
base_class_range vbases()
Definition DeclCXX.h:625
bool isAbstract() const
Determine whether this class has a pure virtual function.
Definition DeclCXX.h:1221
bool isDynamicClass() const
Definition DeclCXX.h:574
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
Definition DeclCXX.cpp:1736
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
Definition DeclCXX.h:623
const CXXBaseSpecifier *const * path_const_iterator
Definition Expr.h:3677
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
bool isZero() const
isZero - Test whether the quantity equals zero.
Definition CharUnits.h:122
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
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:3760
bool hasAttr() const
Definition DeclBase.h:577
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:831
This represents one expression.
Definition Expr.h:112
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition Expr.cpp:273
Represents a member of a struct/union/class.
Definition Decl.h:3160
Represents a function declaration or definition.
Definition Decl.h:2000
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
Definition Decl.cpp:4197
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition Decl.cpp:4185
bool isDestroyingOperatorDelete() const
Determine whether this is a destroying operator delete.
Definition Decl.cpp:3543
ArrayRef< ParmVarDecl * > parameters() const
Definition Decl.h:2774
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition Decl.h:2377
bool isVariadic() const
Whether this function is variadic.
Definition Decl.cpp:3125
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Definition Decl.cpp:4321
bool isDefaulted() const
Whether this function is defaulted.
Definition Decl.h:2385
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4541
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5266
bool isVariadic() const
Whether this function prototype is variadic.
Definition TypeBase.h:5670
Declaration of a template function.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
QualType getReturnType() const
Definition TypeBase.h:4802
GlobalDecl - represents a global declaration.
Definition GlobalDecl.h:57
CXXCtorType getCtorType() const
Definition GlobalDecl.h:108
const Decl * getDecl() const
Definition GlobalDecl.h:106
Represents a field injected from an anonymous union/struct into the parent scope.
Definition Decl.h:3467
ArrayRef< NamedDecl * > chain() const
Definition Decl.h:3488
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
A (possibly-)qualified type.
Definition TypeBase.h:937
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
Definition TypeBase.h:1545
The collection of all-type qualifiers we support.
Definition TypeBase.h:331
field_range fields() const
Definition Decl.h:4515
Encodes a location in the source.
Stmt - This represents one statement.
Definition Stmt.h:85
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:334
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition Decl.h:3812
bool isUnion() const
Definition Decl.h:3922
A template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:3547
The base class of the type hierarchy.
Definition TypeBase.h:1833
CXXRecordDecl * castAsCXXRecordDecl() const
Definition Type.h:36
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9170
bool isRecordType() const
Definition TypeBase.h:8654
QualType getType() const
Definition Decl.h:723
Represents a variable declaration or definition.
Definition Decl.h:926
#define not
Definition iso646.h:22
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
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
CXXDtorType
C++ destructor types.
Definition ABI.h:34
@ Dtor_Base
Base object dtor.
Definition ABI.h:37
@ Dtor_Complete
Complete object dtor.
Definition ABI.h:36
@ Dtor_Deleting
Deleting dtor.
Definition ABI.h:35
U cast(CodeGen::Address addr)
Definition Address.h:327
static bool addressSpace()
static bool ehCleanupFlags()
static bool aggValueSlotGC()
static bool isMemcpyEquivalentSpecialMember()
static bool hiddenVisibility()
static bool runCleanupsScope()
static bool opCallArgEvaluationOrder()
static bool createInvariantGroup()
static bool isTrivialCtorOrDtor()
static bool assignMemcpyizer()
static bool ctorMemcpyizer()
static bool requiresCleanups()
static bool generateDebugInfo()
static bool incrementProfileCounter()
Similar to AddedStructorArgs, but only notes the number of additional arguments.
const clang::CXXRecordDecl * vtableClass
const clang::CXXRecordDecl * nearestVBase