clang 23.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"
23
24using namespace clang;
25using namespace clang::CIRGen;
26
27/// Return the smallest possible amount of storage that might be allocated
28/// starting from the beginning of an object of a particular class.
29///
30/// This may be smaller than sizeof(RD) if RD has virtual base classes.
32 if (!rd->hasDefinition())
33 return CharUnits::One();
34
35 auto &layout = getASTContext().getASTRecordLayout(rd);
36
37 // If the class is final, then we know that the pointer points to an
38 // object of that type and can use the full alignment.
39 if (rd->isEffectivelyFinal())
40 return layout.getSize();
41
42 // Otherwise, we have to assume it could be a subclass.
43 return std::max(layout.getNonVirtualSize(), CharUnits::One());
44}
45
46/// Checks whether the given constructor is a valid subject for the
47/// complete-to-base constructor delegation optimization, i.e. emitting the
48/// complete constructor as a simple call to the base constructor.
50 const CXXConstructorDecl *ctor) {
51 // Currently we disable the optimization for classes with virtual bases
52 // because (1) the address of parameter variables need to be consistent across
53 // all initializers but (2) the delegate function call necessarily creates a
54 // second copy of the parameter variable.
55 //
56 // The limiting example (purely theoretical AFAIK):
57 // struct A { A(int &c) { c++; } };
58 // struct A : virtual A {
59 // B(int count) : A(count) { printf("%d\n", count); }
60 // };
61 // ...although even this example could in principle be emitted as a delegation
62 // since the address of the parameter doesn't escape.
63 if (ctor->getParent()->getNumVBases())
64 return false;
65
66 // We also disable the optimization for variadic functions because it's
67 // impossible to "re-pass" varargs.
68 if (ctor->getType()->castAs<FunctionProtoType>()->isVariadic())
69 return false;
70
71 // FIXME: Decide if we can do a delegation of a delegating constructor.
72 if (ctor->isDelegatingConstructor())
73 return false;
74
75 return true;
76}
77
79 CXXCtorInitializer *memberInit,
80 LValue &lhs) {
81 FieldDecl *field = memberInit->getAnyMember();
82 if (memberInit->isIndirectMemberInitializer()) {
83 // If we are initializing an anonymous union field, drill down to the field.
84 IndirectFieldDecl *indirectField = memberInit->getIndirectMember();
85 for (const auto *nd : indirectField->chain()) {
86 auto *fd = cast<clang::FieldDecl>(nd);
87 lhs = cgf.emitLValueForFieldInitialization(lhs, fd, fd->getName());
88 }
89 } else {
90 lhs = cgf.emitLValueForFieldInitialization(lhs, field, field->getName());
91 }
92}
93
95 const CXXRecordDecl *classDecl,
96 CXXCtorInitializer *memberInit,
97 const CXXConstructorDecl *constructor,
98 FunctionArgList &args) {
99 assert(memberInit->isAnyMemberInitializer() &&
100 "Must have member initializer!");
101 assert(memberInit->getInit() && "Must have initializer!");
102
104
105 // non-static data member initializers
106 FieldDecl *field = memberInit->getAnyMember();
107 QualType fieldType = field->getType();
108
109 mlir::Value thisPtr = cgf.loadCXXThis();
110 CanQualType recordTy = cgf.getContext().getCanonicalTagType(classDecl);
111
112 // If a base constructor is being emitted, create an LValue that has the
113 // non-virtual alignment.
114 LValue lhs = (cgf.curGD.getCtorType() == Ctor_Base)
115 ? cgf.makeNaturalAlignPointeeAddrLValue(thisPtr, recordTy)
116 : cgf.makeNaturalAlignAddrLValue(thisPtr, recordTy);
117
118 emitLValueForAnyFieldInitialization(cgf, memberInit, lhs);
119
120 // Special case: If we are in a copy or move constructor, and we are copying
121 // an array off PODs or classes with trivial copy constructors, ignore the AST
122 // and perform the copy we know is equivalent.
123 // FIXME: This is hacky at best... if we had a bit more explicit information
124 // in the AST, we could generalize it more easily.
125 const ConstantArrayType *array =
126 cgf.getContext().getAsConstantArrayType(fieldType);
127 if (array && constructor->isDefaulted() &&
128 constructor->isCopyOrMoveConstructor()) {
129 QualType baseElementTy = cgf.getContext().getBaseElementType(array);
130 // NOTE(cir): CodeGen allows record types to be memcpy'd if applicable,
131 // whereas ClangIR wants to represent all object construction explicitly.
132 if (!baseElementTy->isRecordType()) {
133 unsigned srcArgIndex =
134 cgf.cgm.getCXXABI().getSrcArgforCopyCtor(constructor, args);
135 cir::LoadOp srcPtr = cgf.getBuilder().createLoad(
136 cgf.getLoc(memberInit->getSourceLocation()),
137 cgf.getAddrOfLocalVar(args[srcArgIndex]));
138 LValue thisRhslv = cgf.makeNaturalAlignAddrLValue(srcPtr, recordTy);
139 LValue src = cgf.emitLValueForFieldInitialization(thisRhslv, field,
140 field->getName());
141
142 // Copy the aggregate.
143 cgf.emitAggregateCopy(lhs, src, fieldType,
144 cgf.getOverlapForFieldInit(field),
145 lhs.isVolatileQualified());
146 // Ensure that we destroy the objects if an exception is thrown later in
147 // the constructor.
148 assert(!cgf.needsEHCleanup(fieldType.isDestructedType()) &&
149 "Arrays of non-record types shouldn't need EH cleanup");
150 return;
151 }
152 }
153
154 cgf.emitInitializerForField(field, lhs, memberInit->getInit());
155}
156
158 const Type *baseType = baseInit->getBaseClass();
159 const auto *baseClassDecl = baseType->castAsCXXRecordDecl();
160 return baseClassDecl->isDynamicClass();
161}
162
163namespace {
164/// Call the destructor for a direct base class.
165struct CallBaseDtor final : EHScopeStack::Cleanup {
166 const CXXRecordDecl *baseClass;
167 bool baseIsVirtual;
168 CallBaseDtor(const CXXRecordDecl *base, bool baseIsVirtual)
169 : baseClass(base), baseIsVirtual(baseIsVirtual) {}
170
171 void emit(CIRGenFunction &cgf, Flags flags) override {
172 const CXXRecordDecl *derivedClass =
173 cast<CXXMethodDecl>(cgf.curFuncDecl)->getParent();
174
175 const CXXDestructorDecl *d = baseClass->getDestructor();
176 // We are already inside a destructor, so presumably the object being
177 // destroyed should have the expected type.
178 QualType thisTy = d->getFunctionObjectParameterType();
179 assert(cgf.currSrcLoc && "expected source location");
180 Address addr = cgf.getAddressOfDirectBaseInCompleteClass(
181 *cgf.currSrcLoc, cgf.loadCXXThisAddress(), derivedClass, baseClass,
182 baseIsVirtual);
183 cgf.emitCXXDestructorCall(d, Dtor_Base, baseIsVirtual,
184 /*delegating=*/false, addr, thisTy);
185 }
186};
187
188/// A visitor which checks whether an initializer uses 'this' in a
189/// way which requires the vtable to be properly set.
190struct DynamicThisUseChecker
191 : ConstEvaluatedExprVisitor<DynamicThisUseChecker> {
192 using super = ConstEvaluatedExprVisitor<DynamicThisUseChecker>;
193
194 bool usesThis = false;
195
196 DynamicThisUseChecker(const ASTContext &c) : super(c) {}
197
198 // Black-list all explicit and implicit references to 'this'.
199 //
200 // Do we need to worry about external references to 'this' derived
201 // from arbitrary code? If so, then anything which runs arbitrary
202 // external code might potentially access the vtable.
203 void VisitCXXThisExpr(const CXXThisExpr *e) { usesThis = true; }
204};
205} // end anonymous namespace
206
207static bool baseInitializerUsesThis(ASTContext &c, const Expr *init) {
208 DynamicThisUseChecker checker(c);
209 checker.Visit(init);
210 return checker.usesThis;
211}
212
213/// Gets the address of a direct base class within a complete object.
214/// This should only be used for (1) non-virtual bases or (2) virtual bases
215/// when the type is known to be complete (e.g. in complete destructors).
216///
217/// The object pointed to by 'thisAddr' is assumed to be non-null.
219 mlir::Location loc, Address thisAddr, const CXXRecordDecl *derived,
220 const CXXRecordDecl *base, bool baseIsVirtual) {
221 // 'thisAddr' must be a pointer (in some address space) to Derived.
222 assert(thisAddr.getElementType() == convertType(derived));
223
224 // Compute the offset of the virtual base.
225 CharUnits offset;
226 const ASTRecordLayout &layout = getContext().getASTRecordLayout(derived);
227 if (baseIsVirtual)
228 offset = layout.getVBaseClassOffset(base);
229 else
230 offset = layout.getBaseClassOffset(base);
231
232 return builder.createBaseClassAddr(loc, thisAddr, convertType(base),
233 offset.getQuantity(),
234 /*assumeNotNull=*/true);
235}
236
238 const CXXRecordDecl *classDecl,
239 CXXCtorInitializer *baseInit) {
240 assert(curFuncDecl && "loading 'this' without a func declaration?");
242
243 assert(baseInit->isBaseInitializer() && "Must have base initializer!");
244
245 Address thisPtr = loadCXXThisAddress();
246
247 const Type *baseType = baseInit->getBaseClass();
248 const auto *baseClassDecl = baseType->castAsCXXRecordDecl();
249
250 bool isBaseVirtual = baseInit->isBaseVirtual();
251
252 // If the initializer for the base (other than the constructor
253 // itself) accesses 'this' in any way, we need to initialize the
254 // vtables.
255 if (baseInitializerUsesThis(getContext(), baseInit->getInit()))
256 initializeVTablePointers(loc, classDecl);
257
258 // We can pretend to be a complete class because it only matters for
259 // virtual bases, and we only do virtual bases for complete ctors.
261 loc, thisPtr, classDecl, baseClassDecl, isBaseVirtual);
265 getOverlapForBaseInit(classDecl, baseClassDecl, isBaseVirtual));
266
267 emitAggExpr(baseInit->getInit(), aggSlot);
268
270}
271
272/// This routine generates necessary code to initialize base classes and
273/// non-static data members belonging to this constructor.
275 CXXCtorType ctorType,
276 FunctionArgList &args) {
277 if (cd->isDelegatingConstructor()) {
279 return;
280 }
281
282 const CXXRecordDecl *classDecl = cd->getParent();
283
284 // Virtual base initializers aren't needed if:
285 // - This is a base ctor variant
286 // - There are no vbases
287 // - The class is abstract, so a complete object of it cannot be constructed
288 //
289 // The check for an abstract class is necessary because sema may not have
290 // marked virtual base destructors referenced.
291 bool constructVBases = ctorType != Ctor_Base &&
292 classDecl->getNumVBases() != 0 &&
293 !classDecl->isAbstract();
294 if (constructVBases &&
295 !cgm.getTarget().getCXXABI().hasConstructorVariants()) {
296 cgm.errorNYI(cd->getSourceRange(),
297 "emitCtorPrologue: virtual base without variants");
298 return;
299 }
300
301 // Create three separate ranges for the different types of initializers.
302 auto allInits = cd->inits();
303
304 // Find the boundaries between the three groups.
305 auto virtualBaseEnd = std::find_if(
306 allInits.begin(), allInits.end(), [](const CXXCtorInitializer *Init) {
307 return !(Init->isBaseInitializer() && Init->isBaseVirtual());
308 });
309
310 auto nonVirtualBaseEnd = std::find_if(virtualBaseEnd, allInits.end(),
311 [](const CXXCtorInitializer *Init) {
312 return !Init->isBaseInitializer();
313 });
314
315 // Create the three ranges.
316 auto virtualBaseInits = llvm::make_range(allInits.begin(), virtualBaseEnd);
317 auto nonVirtualBaseInits =
318 llvm::make_range(virtualBaseEnd, nonVirtualBaseEnd);
319 auto memberInits = llvm::make_range(nonVirtualBaseEnd, allInits.end());
320
321 const mlir::Value oldThisValue = cxxThisValue;
322
323 auto emitInitializer = [&](CXXCtorInitializer *baseInit) {
324 if (cgm.getCodeGenOpts().StrictVTablePointers &&
325 cgm.getCodeGenOpts().OptimizationLevel > 0 &&
326 isInitializerOfDynamicClass(baseInit)) {
327 // It's OK to continue after emitting the error here. The missing code
328 // just "launders" the 'this' pointer.
329 cgm.errorNYI(cd->getSourceRange(),
330 "emitCtorPrologue: strict vtable pointers for vbase");
331 }
332 emitBaseInitializer(getLoc(cd->getBeginLoc()), classDecl, baseInit);
333 };
334
335 // Process virtual base initializers.
336 for (CXXCtorInitializer *virtualBaseInit : virtualBaseInits) {
337 if (!constructVBases)
338 continue;
339 emitInitializer(virtualBaseInit);
340 }
341
343
344 // Then, non-virtual base initializers.
345 for (CXXCtorInitializer *nonVirtualBaseInit : nonVirtualBaseInits) {
346 assert(!nonVirtualBaseInit->isBaseVirtual());
347 emitInitializer(nonVirtualBaseInit);
348 }
349
350 cxxThisValue = oldThisValue;
351
353
354 // Finally, initialize class members.
356 // Classic codegen uses a special class to attempt to replace member
357 // initializers with memcpy. We could possibly defer that to the
358 // lowering or optimization phases to keep the memory accesses more
359 // explicit. For now, we don't insert memcpy at all.
361 for (CXXCtorInitializer *member : memberInits) {
362 assert(!member->isBaseInitializer());
363 assert(member->isAnyMemberInitializer() &&
364 "Delegating initializer on non-delegating constructor");
365 emitMemberInitializer(*this, cd->getParent(), member, cd, args);
366 }
367}
368
370 mlir::Location loc, CIRGenFunction &cgf, Address addr,
371 CharUnits nonVirtualOffset, mlir::Value virtualOffset,
372 const CXXRecordDecl *derivedClass, const CXXRecordDecl *nearestVBase,
373 mlir::Type baseValueTy = {}, bool assumeNotNull = true) {
374 // Assert that we have something to do.
375 assert(!nonVirtualOffset.isZero() || virtualOffset != nullptr);
376
377 // Compute the offset from the static and dynamic components.
378 mlir::Value baseOffset;
379 if (!nonVirtualOffset.isZero()) {
380 if (virtualOffset) {
381 cgf.cgm.errorNYI(
382 loc,
383 "applyNonVirtualAndVirtualOffset: virtual and non-virtual offset");
384 return Address::invalid();
385 } else {
386 assert(baseValueTy && "expected base type");
387 // If no virtualOffset is present this is the final stop.
388 return cgf.getBuilder().createBaseClassAddr(
389 loc, addr, baseValueTy, nonVirtualOffset.getQuantity(),
390 assumeNotNull);
391 }
392 } else {
393 baseOffset = virtualOffset;
394 }
395
396 // Apply the base offset. cir.ptr_stride adjusts by a number of elements,
397 // not bytes. So the pointer must be cast to a byte pointer and back.
398
399 mlir::Value ptr = addr.getPointer();
400 mlir::Type charPtrType = cgf.cgm.uInt8PtrTy;
401 mlir::Value charPtr = cgf.getBuilder().createBitcast(ptr, charPtrType);
402 mlir::Value adjusted = cir::PtrStrideOp::create(
403 cgf.getBuilder(), loc, charPtrType, charPtr, baseOffset);
404 ptr = cgf.getBuilder().createBitcast(adjusted, ptr.getType());
405
406 // If we have a virtual component, the alignment of the result will
407 // be relative only to the known alignment of that vbase.
408 CharUnits alignment;
409 if (virtualOffset) {
410 assert(nearestVBase && "virtual offset without vbase?");
411 alignment = cgf.cgm.getVBaseAlignment(addr.getAlignment(), derivedClass,
412 nearestVBase);
413 } else {
414 alignment = addr.getAlignment();
415 }
416 alignment = alignment.alignmentAtOffset(nonVirtualOffset);
417
418 return Address(ptr, alignment);
419}
420
422 const VPtr &vptr) {
423 // Compute the address point.
424 mlir::Value vtableAddressPoint =
425 cgm.getCXXABI().getVTableAddressPointInStructor(
426 *this, vptr.vtableClass, vptr.base, vptr.nearestVBase);
427
428 if (!vtableAddressPoint)
429 return;
430
431 // Compute where to store the address point.
432 mlir::Value virtualOffset{};
433 CharUnits nonVirtualOffset = CharUnits::Zero();
434
435 mlir::Type baseValueTy;
436 if (cgm.getCXXABI().isVirtualOffsetNeededForVTableField(*this, vptr)) {
437 // We need to use the virtual base offset offset because the virtual base
438 // might have a different offset in the most derived class.
439 virtualOffset = cgm.getCXXABI().getVirtualBaseClassOffset(
440 loc, *this, loadCXXThisAddress(), vptr.vtableClass, vptr.nearestVBase);
441 nonVirtualOffset = vptr.offsetFromNearestVBase;
442 } else {
443 // We can just use the base offset in the complete class.
444 nonVirtualOffset = vptr.base.getBaseOffset();
445 baseValueTy =
446 convertType(getContext().getCanonicalTagType(vptr.base.getBase()));
447 }
448
449 // Apply the offsets.
450 Address classAddr = loadCXXThisAddress();
451 if (!nonVirtualOffset.isZero() || virtualOffset) {
453 loc, *this, classAddr, nonVirtualOffset, virtualOffset,
454 vptr.vtableClass, vptr.nearestVBase, baseValueTy);
455 }
456
457 // Finally, store the address point. Use the same CIR types as the field.
458 //
459 // vtable field is derived from `this` pointer, therefore they should be in
460 // the same addr space.
462 auto vtablePtr =
463 cir::VTableGetVPtrOp::create(builder, loc, classAddr.getPointer());
464 Address vtableField = Address(vtablePtr, classAddr.getAlignment());
465 builder.createStore(loc, vtableAddressPoint, vtableField);
468}
469
471 const CXXRecordDecl *rd) {
472 // Ignore classes without a vtable.
473 if (!rd->isDynamicClass())
474 return;
475
476 // Initialize the vtable pointers for this class and all of its bases.
477 if (cgm.getCXXABI().doStructorsInitializeVPtrs(rd))
478 for (const auto &vptr : getVTablePointers(rd))
479 initializeVTablePointer(loc, vptr);
480
481 if (rd->getNumVBases())
482 cgm.getCXXABI().initializeHiddenVirtualInheritanceMembers(*this, rd);
483}
484
487 CIRGenFunction::VPtrsVector vptrsResult;
490 /*NearestVBase=*/nullptr,
491 /*OffsetFromNearestVBase=*/CharUnits::Zero(),
492 /*BaseIsNonVirtualPrimaryBase=*/false, vtableClass, vbases,
493 vptrsResult);
494 return vptrsResult;
495}
496
498 const CXXRecordDecl *nearestVBase,
499 CharUnits offsetFromNearestVBase,
500 bool baseIsNonVirtualPrimaryBase,
501 const CXXRecordDecl *vtableClass,
503 VPtrsVector &vptrs) {
504 // If this base is a non-virtual primary base the address point has already
505 // been set.
506 if (!baseIsNonVirtualPrimaryBase) {
507 // Initialize the vtable pointer for this base.
508 VPtr vptr = {base, nearestVBase, offsetFromNearestVBase, vtableClass};
509 vptrs.push_back(vptr);
510 }
511
512 const CXXRecordDecl *rd = base.getBase();
513
514 for (const auto &nextBase : rd->bases()) {
515 const auto *baseDecl =
516 cast<CXXRecordDecl>(nextBase.getType()->castAs<RecordType>()->getDecl())
517 ->getDefinitionOrSelf();
518
519 // Ignore classes without a vtable.
520 if (!baseDecl->isDynamicClass())
521 continue;
522
523 CharUnits baseOffset;
524 CharUnits baseOffsetFromNearestVBase;
525 bool baseDeclIsNonVirtualPrimaryBase;
526 const CXXRecordDecl *nextBaseDecl;
527
528 if (nextBase.isVirtual()) {
529 // Check if we've visited this virtual base before.
530 if (!vbases.insert(baseDecl).second)
531 continue;
532
533 const ASTRecordLayout &layout =
534 getContext().getASTRecordLayout(vtableClass);
535
536 nextBaseDecl = baseDecl;
537 baseOffset = layout.getVBaseClassOffset(baseDecl);
538 baseOffsetFromNearestVBase = CharUnits::Zero();
539 baseDeclIsNonVirtualPrimaryBase = false;
540 } else {
541 const ASTRecordLayout &layout = getContext().getASTRecordLayout(rd);
542
543 nextBaseDecl = nearestVBase;
544 baseOffset = base.getBaseOffset() + layout.getBaseClassOffset(baseDecl);
545 baseOffsetFromNearestVBase =
546 offsetFromNearestVBase + layout.getBaseClassOffset(baseDecl);
547 baseDeclIsNonVirtualPrimaryBase = layout.getPrimaryBase() == baseDecl;
548 }
549
550 getVTablePointers(BaseSubobject(baseDecl, baseOffset), nextBaseDecl,
551 baseOffsetFromNearestVBase,
552 baseDeclIsNonVirtualPrimaryBase, vtableClass, vbases,
553 vptrs);
554 }
555}
556
558 assert(curFuncDecl && "loading 'this' without a func declaration?");
560
561 // Lazily compute CXXThisAlignment.
562 if (cxxThisAlignment.isZero()) {
563 // Just use the best known alignment for the parent.
564 // TODO: if we're currently emitting a complete-object ctor/dtor, we can
565 // always use the complete-object alignment.
566 auto rd = cast<CXXMethodDecl>(curFuncDecl)->getParent();
567 cxxThisAlignment = cgm.getClassPointerAlignment(rd);
568 }
569
571}
572
574 Expr *init) {
575 QualType fieldType = field->getType();
576 switch (getEvaluationKind(fieldType)) {
577 case cir::TEK_Scalar:
578 if (lhs.isSimple()) {
579 emitExprAsInit(init, field, lhs, false);
580 } else {
581 RValue rhs = RValue::get(emitScalarExpr(init));
582 emitStoreThroughLValue(rhs, lhs);
583 }
584 break;
585 case cir::TEK_Complex:
586 emitComplexExprIntoLValue(init, lhs, /*isInit=*/true);
587 break;
588 case cir::TEK_Aggregate: {
594 emitAggExpr(init, slot);
595 break;
596 }
597 }
598
599 // Ensure that we destroy this object if an exception is thrown later in the
600 // constructor.
601 QualType::DestructionKind dtorKind = fieldType.isDestructedType();
602 (void)dtorKind;
604}
605
607 const Expr *e, Address base, mlir::Value memberPtr,
608 const MemberPointerType *memberPtrType, LValueBaseInfo *baseInfo) {
610
611 cir::GetRuntimeMemberOp op = builder.createGetIndirectMember(
612 getLoc(e->getSourceRange()), base.getPointer(), memberPtr);
613
614 QualType memberType = memberPtrType->getPointeeType();
616 CharUnits memberAlign = cgm.getNaturalTypeAlignment(memberType, baseInfo);
617 memberAlign = cgm.getDynamicOffsetAlignment(
618 base.getAlignment(), memberPtrType->getMostRecentCXXRecordDecl(),
619 memberAlign);
620
621 return Address(op, convertTypeForMem(memberPtrType->getPointeeType()),
622 memberAlign);
623}
624
627 const CXXRecordDecl *baseDecl,
628 CharUnits expectedTargetAlign) {
629 // If the base is an incomplete type (which is, alas, possible with
630 // member pointers), be pessimistic.
631 if (!baseDecl->isCompleteDefinition())
632 return std::min(actualBaseAlign, expectedTargetAlign);
633
634 const ASTRecordLayout &baseLayout =
636 CharUnits expectedBaseAlign = baseLayout.getNonVirtualAlignment();
637
638 // If the class is properly aligned, assume the target offset is, too.
639 //
640 // This actually isn't necessarily the right thing to do --- if the
641 // class is a complete object, but it's only properly aligned for a
642 // base subobject, then the alignments of things relative to it are
643 // probably off as well. (Note that this requires the alignment of
644 // the target to be greater than the NV alignment of the derived
645 // class.)
646 //
647 // However, our approach to this kind of under-alignment can only
648 // ever be best effort; after all, we're never going to propagate
649 // alignments through variables or parameters. Note, in particular,
650 // that constructing a polymorphic type in an address that's less
651 // than pointer-aligned will generally trap in the constructor,
652 // unless we someday add some sort of attribute to change the
653 // assumed alignment of 'this'. So our goal here is pretty much
654 // just to allow the user to explicitly say that a pointer is
655 // under-aligned and then safely access its fields and vtables.
656 if (actualBaseAlign >= expectedBaseAlign)
657 return expectedTargetAlign;
658
659 // Otherwise, we might be offset by an arbitrary multiple of the
660 // actual alignment. The correct adjustment is to take the min of
661 // the two alignments.
662 return std::min(actualBaseAlign, expectedTargetAlign);
663}
664
665/// Return the best known alignment for a pointer to a virtual base,
666/// given the alignment of a pointer to the derived class.
669 const CXXRecordDecl *derivedClass,
670 const CXXRecordDecl *vbaseClass) {
671 // The basic idea here is that an underaligned derived pointer might
672 // indicate an underaligned base pointer.
673
674 assert(vbaseClass->isCompleteDefinition());
675 const ASTRecordLayout &baseLayout =
676 getASTContext().getASTRecordLayout(vbaseClass);
677 CharUnits expectedVBaseAlign = baseLayout.getNonVirtualAlignment();
678
679 return getDynamicOffsetAlignment(actualDerivedAlign, derivedClass,
680 expectedVBaseAlign);
681}
682
683/// Emit a loop to call a particular constructor for each of several members
684/// of an array.
685///
686/// \param ctor the constructor to call for each element
687/// \param arrayType the type of the array to initialize
688/// \param arrayBegin an arrayType*
689/// \param zeroInitialize true if each element should be
690/// zero-initialized before it is constructed
693 Address arrayBegin, const CXXConstructExpr *e, bool newPointerIsChecked,
694 bool zeroInitialize) {
695 QualType elementType;
696 mlir::Value numElements = emitArrayLength(arrayType, elementType, arrayBegin);
697 emitCXXAggrConstructorCall(ctor, numElements, arrayBegin, e,
698 newPointerIsChecked, zeroInitialize);
699}
700
701/// Emit a loop to call a particular constructor for each of several members
702/// of an array.
703///
704/// \param ctor the constructor to call for each element
705/// \param numElements the number of elements in the array;
706/// may be zero
707/// \param arrayBase a T*, where T is the type constructed by ctor
708/// \param zeroInitialize true if each element should be
709/// zero-initialized before it is constructed
711 const CXXConstructorDecl *ctor, mlir::Value numElements, Address arrayBase,
712 const CXXConstructExpr *e, bool newPointerIsChecked, bool zeroInitialize) {
713 // It's legal for numElements to be zero. This can happen both
714 // dynamically, because x can be zero in 'new A[x]', and statically,
715 // because of GCC extensions that permit zero-length arrays. There
716 // are probably legitimate places where we could assume that this
717 // doesn't happen, but it's not clear that it's worth it.
718
719 auto arrayTy = mlir::cast<cir::ArrayType>(arrayBase.getElementType());
720 mlir::Type elementType = arrayTy.getElementType();
721
722 // This might be a multi-dimensional array. Find the innermost element type.
723 while (auto maybeArrayTy = mlir::dyn_cast<cir::ArrayType>(elementType))
724 elementType = maybeArrayTy.getElementType();
725 cir::PointerType ptrToElmType = builder.getPointerTo(elementType);
726
727 // Optimize for a constant count.
728 if (auto constantCount = numElements.getDefiningOp<cir::ConstantOp>()) {
729 if (auto constIntAttr = constantCount.getValueAttr<cir::IntAttr>()) {
730 // Just skip out if the constant count is zero.
731 if (constIntAttr.getUInt() == 0)
732 return;
733
734 arrayTy = cir::ArrayType::get(elementType, constIntAttr.getUInt());
735 // Otherwise, emit the check.
736 }
737
738 if (constantCount.use_empty())
739 constantCount.erase();
740 } else {
741 // Otherwise, emit the check.
742 cgm.errorNYI(e->getSourceRange(),
743 "emitCXXAggrConstructorCall: dynamic-length array expression");
744 }
745
746 // Traditional LLVM codegen emits a loop here. CIR lowers to a loop as part of
747 // LoweringPrepare.
748
749 // The alignment of the base, adjusted by the size of a single element,
750 // provides a conservative estimate of the alignment of every element.
751 // (This assumes we never start tracking offsetted alignments.)
752 //
753 // Note that these are complete objects and so we don't need to
754 // use the non-virtual size or alignment.
756 CharUnits eltAlignment = arrayBase.getAlignment().alignmentOfArrayElement(
757 getContext().getTypeSizeInChars(type));
758
759 // C++ [class.temporary]p4:
760 // There are two contexts in which temporaries are destroyed at a different
761 // point than the end of the full-expression. The first context is when a
762 // default constructor is called to initialize an element of an array.
763 // If the constructor has one or more default arguments, the destruction of
764 // every temporary created in a default argument expression is sequenced
765 // before the construction of the next array element, if any.
766 {
767 RunCleanupsScope scope(*this);
768
769 // Evaluate the constructor and its arguments in a regular
770 // partial-destroy cleanup.
771 if (getLangOpts().Exceptions &&
772 !ctor->getParent()->hasTrivialDestructor()) {
773 cgm.errorNYI(e->getSourceRange(), "partial array cleanups");
774 }
775
776 // Emit the constructor call that will execute for every array element.
777 mlir::Value arrayOp =
778 builder.createPtrBitcast(arrayBase.getPointer(), arrayTy);
779 cir::ArrayCtor::create(
780 builder, *currSrcLoc, arrayOp,
781 [&](mlir::OpBuilder &b, mlir::Location loc) {
782 mlir::BlockArgument arg =
783 b.getInsertionBlock()->addArgument(ptrToElmType, loc);
784 Address curAddr = Address(arg, elementType, eltAlignment);
786 // Zero-initialize each element before invoking its constructor,
787 // matching CGClass::EmitCXXAggrConstructorCall which does per-element
788 // zero-init inside the array ctor loop.
789 if (zeroInitialize)
790 emitNullInitialization(loc, curAddr, type);
791 auto currAVS = AggValueSlot::forAddr(
792 curAddr, type.getQualifiers(), AggValueSlot::IsDestructed,
796 /*ForVirtualBase=*/false,
797 /*Delegating=*/false, currAVS, e);
798 cir::YieldOp::create(b, loc);
799 });
800 }
801}
802
804 const CXXConstructorDecl *ctor, CXXCtorType ctorType,
805 const FunctionArgList &args, SourceLocation loc) {
806 CallArgList delegateArgs;
807
808 FunctionArgList::const_iterator i = args.begin(), e = args.end();
809 assert(i != e && "no parameters to constructor");
810
811 // this
812 Address thisAddr = loadCXXThisAddress();
813 delegateArgs.add(RValue::get(thisAddr.getPointer()), (*i)->getType());
814 ++i;
815
816 // FIXME: The location of the VTT parameter in the parameter list is specific
817 // to the Itanium ABI and shouldn't be hardcoded here.
818 if (cgm.getCXXABI().needsVTTParameter(curGD)) {
819 cgm.errorNYI(loc, "emitDelegateCXXConstructorCall: VTT parameter");
820 return;
821 }
822
823 // Explicit arguments.
824 for (; i != e; ++i) {
825 const VarDecl *param = *i;
826 // FIXME: per-argument source location
827 emitDelegateCallArg(delegateArgs, param, loc);
828 }
829
831
832 emitCXXConstructorCall(ctor, ctorType, /*ForVirtualBase=*/false,
833 /*Delegating=*/true, thisAddr, delegateArgs, loc);
834}
835
837 const auto *assignOp = cast<CXXMethodDecl>(curGD.getDecl());
838 assert(assignOp->isCopyAssignmentOperator() ||
839 assignOp->isMoveAssignmentOperator());
840 const Stmt *rootS = assignOp->getBody();
841 assert(isa<CompoundStmt>(rootS) &&
842 "Body of an implicit assignment operator should be compound stmt.");
843 const auto *rootCS = cast<CompoundStmt>(rootS);
844
845 cgm.setCXXSpecialMemberAttr(cast<cir::FuncOp>(curFn), assignOp);
846
849
850 // Classic codegen uses a special class to attempt to replace member
851 // initializers with memcpy. We could possibly defer that to the
852 // lowering or optimization phases to keep the memory accesses more
853 // explicit. For now, we don't insert memcpy at all, though in some
854 // cases the AST contains a call to memcpy.
856 for (Stmt *s : rootCS->body())
857 if (emitStmt(s, /*useCurrentScope=*/true).failed())
858 cgm.errorNYI(s->getSourceRange(),
859 std::string("emitImplicitAssignmentOperatorBody: ") +
860 s->getStmtClassName());
861}
862
864 const CXXMethodDecl *callOperator, CallArgList &callArgs) {
865 // Get the address of the call operator.
866 const CIRGenFunctionInfo &calleeFnInfo =
867 cgm.getTypes().arrangeCXXMethodDeclaration(callOperator);
868 cir::FuncOp calleePtr = cgm.getAddrOfFunction(
869 GlobalDecl(callOperator), cgm.getTypes().getFunctionType(calleeFnInfo));
870
871 // Prepare the return slot.
872 const FunctionProtoType *fpt =
873 callOperator->getType()->castAs<FunctionProtoType>();
874 QualType resultType = fpt->getReturnType();
875 ReturnValueSlot returnSlot;
876
877 // We don't need to separately arrange the call arguments because
878 // the call can't be variadic anyway --- it's impossible to forward
879 // variadic arguments.
880
881 // Now emit our call.
882 CIRGenCallee callee =
883 CIRGenCallee::forDirect(calleePtr, GlobalDecl(callOperator));
884 RValue rv = emitCall(calleeFnInfo, callee, returnSlot, callArgs);
885
886 // If necessary, copy the returned value into the slot.
887 if (!resultType->isVoidType() && returnSlot.isNull()) {
888 if (getLangOpts().ObjCAutoRefCount && resultType->isObjCRetainableType())
889 cgm.errorNYI(callOperator->getSourceRange(),
890 "emitForwardingCallToLambda: ObjCAutoRefCount");
891 emitReturnOfRValue(*currSrcLoc, rv, resultType);
892 } else {
893 cgm.errorNYI(callOperator->getSourceRange(),
894 "emitForwardingCallToLambda: return slot is not null");
895 }
896}
897
899 const CXXRecordDecl *lambda = md->getParent();
900
901 // Start building arguments for forwarding call
902 CallArgList callArgs;
903
904 QualType lambdaType = getContext().getCanonicalTagType(lambda);
905 QualType thisType = getContext().getPointerType(lambdaType);
906 Address thisPtr =
907 createMemTemp(lambdaType, getLoc(md->getSourceRange()), "unused.capture");
908 callArgs.add(RValue::get(thisPtr.getPointer()), thisType);
909
910 // Add the rest of the parameters.
911 for (auto *param : md->parameters())
912 emitDelegateCallArg(callArgs, param, param->getBeginLoc());
913
914 const CXXMethodDecl *callOp = lambda->getLambdaCallOperator();
915 // For a generic lambda, find the corresponding call operator specialization
916 // to which the call to the static-invoker shall be forwarded.
917 if (lambda->isGenericLambda()) {
920 FunctionTemplateDecl *callOpTemplate =
922 void *InsertPos = nullptr;
923 FunctionDecl *correspondingCallOpSpecialization =
924 callOpTemplate->findSpecialization(tal->asArray(), InsertPos);
925 assert(correspondingCallOpSpecialization);
926 callOp = cast<CXXMethodDecl>(correspondingCallOpSpecialization);
927 }
928 emitForwardingCallToLambda(callOp, callArgs);
929}
930
932 if (md->isVariadic()) {
933 // Codgen for LLVM doesn't emit code for this as well, it says:
934 // FIXME: Making this work correctly is nasty because it requires either
935 // cloning the body of the call operator or making the call operator
936 // forward.
937 cgm.errorNYI(md->getSourceRange(), "emitLambdaStaticInvokeBody: variadic");
938 }
939
941}
942
944 QualType type) {
945 const auto *record = type->castAsCXXRecordDecl();
946 const CXXDestructorDecl *dtor = record->getDestructor();
947 // TODO(cir): Unlike traditional codegen, CIRGen should actually emit trivial
948 // dtors which shall be removed on later CIR passes. However, only remove this
949 // assertion after we have a test case to exercise this path.
950 assert(!dtor->isTrivial());
951 cgf.emitCXXDestructorCall(dtor, Dtor_Complete, /*forVirtualBase*/ false,
952 /*delegating=*/false, addr, type);
953}
954
955namespace {
956mlir::Value loadThisForDtorDelete(CIRGenFunction &cgf,
957 const CXXDestructorDecl *dd) {
958 if (Expr *thisArg = dd->getOperatorDeleteThisArg())
959 return cgf.emitScalarExpr(thisArg);
960 return cgf.loadCXXThis();
961}
962
963/// Call the operator delete associated with the current destructor.
964struct CallDtorDelete final : EHScopeStack::Cleanup {
965 CallDtorDelete() {}
966
967 void emit(CIRGenFunction &cgf, Flags flags) override {
968 const CXXDestructorDecl *dtor = cast<CXXDestructorDecl>(cgf.curFuncDecl);
969 const CXXRecordDecl *classDecl = dtor->getParent();
971 loadThisForDtorDelete(cgf, dtor),
972 cgf.getContext().getCanonicalTagType(classDecl));
973 }
974};
975
976class DestroyField final : public EHScopeStack::Cleanup {
977 const FieldDecl *field;
978 CIRGenFunction::Destroyer *destroyer;
979
980public:
981 DestroyField(const FieldDecl *field, CIRGenFunction::Destroyer *destroyer)
982 : field(field), destroyer(destroyer) {}
983
984 void emit(CIRGenFunction &cgf, Flags flags) override {
985 // Find the address of the field.
986 Address thisValue = cgf.loadCXXThisAddress();
987 CanQualType recordTy =
988 cgf.getContext().getCanonicalTagType(field->getParent());
989 LValue thisLV = cgf.makeAddrLValue(thisValue, recordTy);
990 LValue lv = cgf.emitLValueForField(thisLV, field);
991 assert(lv.isSimple());
992
994 cgf.emitDestroy(lv.getAddress(), field->getType(), destroyer);
995 }
996};
997} // namespace
998
999/// Emit all code that comes at the end of class's destructor. This is to call
1000/// destructors on members and base classes in reverse order of their
1001/// construction.
1002///
1003/// For a deleting destructor, this also handles the case where a destroying
1004/// operator delete completely overrides the definition.
1006 CXXDtorType dtorType) {
1007 assert((!dd->isTrivial() || dd->hasAttr<DLLExportAttr>()) &&
1008 "Should not emit dtor epilogue for non-exported trivial dtor!");
1009
1010 // The deleting-destructor phase just needs to call the appropriate
1011 // operator delete that Sema picked up.
1012 if (dtorType == Dtor_Deleting) {
1013 assert(dd->getOperatorDelete() &&
1014 "operator delete missing - EnterDtorCleanups");
1016 cgm.errorNYI(dd->getSourceRange(), "deleting destructor with vtt");
1017 } else {
1019 cgm.errorNYI(dd->getSourceRange(),
1020 "deleting destructor with destroying operator delete");
1021 } else {
1022 ehStack.pushCleanup<CallDtorDelete>(NormalAndEHCleanup);
1023 }
1024 }
1025 return;
1026 }
1027
1028 const CXXRecordDecl *classDecl = dd->getParent();
1029
1030 // Unions have no bases and do not call field destructors.
1031 if (classDecl->isUnion())
1032 return;
1033
1034 // The complete-destructor phase just destructs all the virtual bases.
1035 if (dtorType == Dtor_Complete) {
1037
1038 // We push them in the forward order so that they'll be popped in
1039 // the reverse order.
1040 for (const CXXBaseSpecifier &base : classDecl->vbases()) {
1041 auto *baseClassDecl = base.getType()->castAsCXXRecordDecl();
1042
1043 if (baseClassDecl->hasTrivialDestructor()) {
1044 // Under SanitizeMemoryUseAfterDtor, poison the trivial base class
1045 // memory. For non-trival base classes the same is done in the class
1046 // destructor.
1048 } else {
1049 ehStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, baseClassDecl,
1050 /*baseIsVirtual=*/true);
1051 }
1052 }
1053
1054 return;
1055 }
1056
1057 assert(dtorType == Dtor_Base);
1059
1060 // Destroy non-virtual bases.
1061 for (const CXXBaseSpecifier &base : classDecl->bases()) {
1062 // Ignore virtual bases.
1063 if (base.isVirtual())
1064 continue;
1065
1066 CXXRecordDecl *baseClassDecl = base.getType()->getAsCXXRecordDecl();
1067
1068 if (baseClassDecl->hasTrivialDestructor())
1070 else
1071 ehStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, baseClassDecl,
1072 /*baseIsVirtual=*/false);
1073 }
1074
1076
1077 // Destroy direct fields.
1078 for (const FieldDecl *field : classDecl->fields()) {
1079 QualType type = field->getType();
1080 QualType::DestructionKind dtorKind = type.isDestructedType();
1081 if (!dtorKind)
1082 continue;
1083
1084 // Anonymous union members do not have their destructors called.
1085 const RecordType *rt = type->getAsUnionType();
1086 if (rt && rt->getDecl()->isAnonymousStructOrUnion())
1087 continue;
1088
1089 CleanupKind cleanupKind = getCleanupKind(dtorKind);
1091 ehStack.pushCleanup<DestroyField>(cleanupKind, field,
1092 getDestroyer(dtorKind));
1093 }
1094}
1095
1097 const CXXConstructorDecl *ctor, const FunctionArgList &args) {
1098 assert(ctor->isDelegatingConstructor());
1099
1100 Address thisPtr = loadCXXThisAddress();
1101
1108
1109 emitAggExpr(ctor->init_begin()[0]->getInit(), aggSlot);
1110
1111 const CXXRecordDecl *classDecl = ctor->getParent();
1112 if (cgm.getLangOpts().Exceptions && !classDecl->hasTrivialDestructor()) {
1113 cgm.errorNYI(ctor->getSourceRange(),
1114 "emitDelegatingCXXConstructorCall: exception");
1115 return;
1116 }
1117}
1118
1121 bool forVirtualBase, bool delegating,
1122 Address thisAddr, QualType thisTy) {
1123 cgm.getCXXABI().emitDestructorCall(*this, dd, type, forVirtualBase,
1124 delegating, thisAddr, thisTy);
1125}
1126
1127mlir::Value CIRGenFunction::getVTTParameter(GlobalDecl gd, bool forVirtualBase,
1128 bool delegating) {
1129 if (!cgm.getCXXABI().needsVTTParameter(gd))
1130 return nullptr;
1131
1132 const CXXRecordDecl *rd = cast<CXXMethodDecl>(curCodeDecl)->getParent();
1133 const CXXRecordDecl *base = cast<CXXMethodDecl>(gd.getDecl())->getParent();
1134
1135 uint64_t subVTTIndex;
1136
1137 if (delegating) {
1138 // If this is a delegating constructor call, just load the VTT.
1139 return loadCXXVTT();
1140 } else if (rd == base) {
1141 // If the record matches the base, this is the complete ctor/dtor
1142 // variant calling the base variant in a class with virtual bases.
1143 assert(!cgm.getCXXABI().needsVTTParameter(curGD) &&
1144 "doing no-op VTT offset in base dtor/ctor?");
1145 assert(!forVirtualBase && "Can't have same class as virtual base!");
1146 subVTTIndex = 0;
1147 } else {
1148 const ASTRecordLayout &layout = getContext().getASTRecordLayout(rd);
1149 CharUnits baseOffset = forVirtualBase ? layout.getVBaseClassOffset(base)
1150 : layout.getBaseClassOffset(base);
1151
1152 subVTTIndex =
1153 cgm.getVTables().getSubVTTIndex(rd, BaseSubobject(base, baseOffset));
1154 assert(subVTTIndex != 0 && "Sub-VTT index must be greater than zero!");
1155 }
1156
1157 mlir::Location loc = cgm.getLoc(rd->getBeginLoc());
1158 if (cgm.getCXXABI().needsVTTParameter(curGD)) {
1159 // A VTT parameter was passed to the constructor, use it.
1160 mlir::Value vtt = loadCXXVTT();
1161 return builder.createVTTAddrPoint(loc, vtt.getType(), vtt, subVTTIndex);
1162 } else {
1163 // We're the complete constructor, so get the VTT by name.
1164 cir::GlobalOp vtt = cgm.getVTables().getAddrOfVTT(rd);
1165 return builder.createVTTAddrPoint(
1166 loc, builder.getPointerTo(cgm.voidPtrTy),
1167 mlir::FlatSymbolRefAttr::get(vtt.getSymNameAttr()), subVTTIndex);
1168 }
1169}
1170
1172 mlir::Location loc, Address baseAddr, const CXXRecordDecl *derived,
1173 llvm::iterator_range<CastExpr::path_const_iterator> path,
1174 bool nullCheckValue) {
1175 assert(!path.empty() && "Base path should not be empty!");
1176
1177 QualType derivedTy = getContext().getCanonicalTagType(derived);
1178 mlir::Type derivedValueTy = convertType(derivedTy);
1179 CharUnits nonVirtualOffset =
1180 cgm.computeNonVirtualBaseClassOffset(derived, path);
1181
1182 // Note that in OG, no offset (nonVirtualOffset.getQuantity() == 0) means it
1183 // just gives the address back. In CIR a `cir.derived_class` is created and
1184 // made into a nop later on during lowering.
1185 return builder.createDerivedClassAddr(loc, baseAddr, derivedValueTy,
1186 nonVirtualOffset.getQuantity(),
1187 /*assumeNotNull=*/!nullCheckValue);
1188}
1189
1191 Address value, const CXXRecordDecl *derived,
1192 llvm::iterator_range<CastExpr::path_const_iterator> path,
1193 bool nullCheckValue, SourceLocation loc) {
1194 assert(!path.empty() && "Base path should not be empty!");
1195
1196 CastExpr::path_const_iterator start = path.begin();
1197 const CXXRecordDecl *vBase = nullptr;
1198
1199 if ((*path.begin())->isVirtual()) {
1200 vBase = (*start)->getType()->castAsCXXRecordDecl();
1201 ++start;
1202 }
1203
1204 // Compute the static offset of the ultimate destination within its
1205 // allocating subobject (the virtual base, if there is one, or else
1206 // the "complete" object that we see).
1207 CharUnits nonVirtualOffset = cgm.computeNonVirtualBaseClassOffset(
1208 vBase ? vBase : derived, {start, path.end()});
1209
1210 // If there's a virtual step, we can sometimes "devirtualize" it.
1211 // For now, that's limited to when the derived type is final.
1212 // TODO: "devirtualize" this for accesses to known-complete objects.
1213 if (vBase && derived->hasAttr<FinalAttr>()) {
1214 const ASTRecordLayout &layout = getContext().getASTRecordLayout(derived);
1215 CharUnits vBaseOffset = layout.getVBaseClassOffset(vBase);
1216 nonVirtualOffset += vBaseOffset;
1217 vBase = nullptr; // we no longer have a virtual step
1218 }
1219
1220 // Get the base pointer type.
1221 mlir::Type baseValueTy = convertType((path.end()[-1])->getType());
1223
1224 // If there is no virtual base, use cir.base_class_addr. It takes care of
1225 // the adjustment and the null pointer check.
1226 if (nonVirtualOffset.isZero() && !vBase) {
1228 return builder.createBaseClassAddr(getLoc(loc), value, baseValueTy, 0,
1229 /*assumeNotNull=*/true);
1230 }
1231
1233
1234 // Compute the virtual offset.
1235 mlir::Value virtualOffset = nullptr;
1236 if (vBase) {
1237 virtualOffset = cgm.getCXXABI().getVirtualBaseClassOffset(
1238 getLoc(loc), *this, value, derived, vBase);
1239 }
1240
1241 // Apply both offsets.
1243 getLoc(loc), *this, value, nonVirtualOffset, virtualOffset, derived,
1244 vBase, baseValueTy, not nullCheckValue);
1245
1246 // Cast to the destination type.
1247 value = value.withElementType(builder, baseValueTy);
1248
1249 return value;
1250}
1251
1252// TODO(cir): this can be shared with LLVM codegen.
1255 if (!cgm.getCodeGenOpts().WholeProgramVTables)
1256 return false;
1257
1258 if (cgm.getCodeGenOpts().VirtualFunctionElimination)
1259 return true;
1260
1262
1263 return false;
1264}
1265
1266mlir::Value CIRGenFunction::getVTablePtr(mlir::Location loc, Address thisAddr,
1267 const CXXRecordDecl *rd) {
1268 auto vtablePtr =
1269 cir::VTableGetVPtrOp::create(builder, loc, thisAddr.getPointer());
1270 Address vtablePtrAddr = Address(vtablePtr, thisAddr.getAlignment());
1271
1272 auto vtable = builder.createLoad(loc, vtablePtrAddr);
1274
1275 if (cgm.getCodeGenOpts().OptimizationLevel > 0 &&
1276 cgm.getCodeGenOpts().StrictVTablePointers) {
1278 }
1279
1280 return vtable;
1281}
1282
1285 bool forVirtualBase,
1286 bool delegating,
1287 AggValueSlot thisAVS,
1288 const clang::CXXConstructExpr *e) {
1289 CallArgList args;
1290 Address thisAddr = thisAVS.getAddress();
1291 QualType thisType = d->getThisType();
1292 mlir::Value thisPtr = thisAddr.getPointer();
1293
1295
1296 args.add(RValue::get(thisPtr), thisType);
1297
1298 // In LLVM Codegen: If this is a trivial constructor, just emit what's needed.
1299 // If this is a union copy constructor, we must emit a memcpy, because the AST
1300 // does not model that copy.
1302
1303 const FunctionProtoType *fpt = d->getType()->castAs<FunctionProtoType>();
1304
1306
1307 emitCallArgs(args, fpt, e->arguments(), e->getConstructor(),
1308 /*ParamsToSkip=*/0);
1309
1311 emitCXXConstructorCall(d, type, forVirtualBase, delegating, thisAddr, args,
1312 e->getExprLoc());
1313}
1314
1316 const CXXConstructorDecl *d, CXXCtorType type, bool forVirtualBase,
1317 bool delegating, Address thisAddr, CallArgList &args, SourceLocation loc) {
1318
1319 const CXXRecordDecl *crd = d->getParent();
1320
1321 // If this is a call to a trivial default constructor:
1322 // In LLVM: do nothing.
1323 // In CIR: emit as a regular call, other later passes should lower the
1324 // ctor call into trivial initialization.
1326
1328
1329 bool passPrototypeArgs = true;
1330
1331 // Check whether we can actually emit the constructor before trying to do so.
1332 if (d->getInheritedConstructor()) {
1333 cgm.errorNYI(d->getSourceRange(),
1334 "emitCXXConstructorCall: inherited constructor");
1335 return;
1336 }
1337
1338 // Insert any ABI-specific implicit constructor arguments.
1340 cgm.getCXXABI().addImplicitConstructorArgs(*this, d, type, forVirtualBase,
1341 delegating, args);
1342
1343 // Emit the call.
1344 auto calleePtr = cgm.getAddrOfCXXStructor(GlobalDecl(d, type));
1345 const CIRGenFunctionInfo &info = cgm.getTypes().arrangeCXXConstructorCall(
1346 args, d, type, extraArgs.prefix, extraArgs.suffix, passPrototypeArgs);
1347 CIRGenCallee callee = CIRGenCallee::forDirect(calleePtr, GlobalDecl(d, type));
1348 cir::CIRCallOpInterface c;
1349 emitCall(info, callee, ReturnValueSlot(), args, &c, getLoc(loc));
1350
1351 if (cgm.getCodeGenOpts().OptimizationLevel != 0 && !crd->isDynamicClass() &&
1352 type != Ctor_Base && cgm.getCodeGenOpts().StrictVTablePointers)
1353 cgm.errorNYI(d->getSourceRange(), "vtable assumption loads");
1354}
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:226
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 getSize() const
getSize - Get the record size in characters.
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:3772
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:96
mlir::Type getElementType() const
Definition Address.h:123
static Address invalid()
Definition Address.h:74
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:136
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)
cir::LoadOp createLoad(mlir::Location loc, Address addr, bool isVolatile=false)
virtual size_t getSrcArgforCopyCtor(const CXXConstructorDecl *, FunctionArgList &args) const =0
static CIRGenCallee forDirect(mlir::Operation *funcPtr, const CIRGenCalleeInfo &abstractInfo=CIRGenCalleeInfo())
Definition CIRGenCall.h:92
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...
Address emitCXXMemberDataPointerAddress(const Expr *e, Address base, mlir::Value memberPtr, const MemberPointerType *memberPtrType, LValueBaseInfo *baseInfo)
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)
const clang::Decl * curFuncDecl
Address getAddrOfLocalVar(const clang::VarDecl *vd)
Return the address of a local variable.
void emitAggregateCopy(LValue dest, LValue src, QualType eltTy, AggValueSlot::Overlap_t mayOverlap, bool isVolatile=false)
Emit an aggregate copy.
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)
mlir::Operation * curFn
The current function or global initializer that is generated code for.
Address getAddressOfDerivedClass(mlir::Location loc, Address baseAddr, const CXXRecordDecl *derived, llvm::iterator_range< CastExpr::path_const_iterator > path, bool nullCheckValue)
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)
mlir::Type convertTypeForMem(QualType t)
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...
void emitInitializerForField(clang::FieldDecl *field, LValue lhs, clang::Expr *init)
LValue emitLValueForField(LValue base, const clang::FieldDecl *field)
mlir::Value emitScalarExpr(const clang::Expr *e, bool ignoreResultAssign=false)
Emit the computation of the specified expression of scalar type.
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind.
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 getMinimumClassObjectSize(const CXXRecordDecl *cd)
Returns the minimum object size for an object of the given class type (or a class derived from it).
CharUnits getVBaseAlignment(CharUnits derivedAlign, const CXXRecordDecl *derived, const CXXRecordDecl *vbase)
Returns the assumed alignment of a virtual base of a class.
CIRGenCXXABI & getCXXABI() const
void add(RValue rvalue, clang::QualType type)
Definition CIRGenCall.h:239
Information for lazily generating a cleanup.
Type for representing both the decl and type of parameters to a function.
Definition CIRGenCall.h:193
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:83
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 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:2611
init_iterator init_begin()
Retrieve an iterator to the first initializer.
Definition DeclCXX.h:2708
bool isDelegatingConstructor() const
Determine whether this constructor is a delegating constructor.
Definition DeclCXX.h:2764
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
Definition DeclCXX.cpp:3037
InheritedConstructor getInheritedConstructor() const
Get the constructor that this inheriting constructor is based on.
Definition DeclCXX.h:2849
Represents a C++ base or member initializer.
Definition DeclCXX.h:2376
Expr * getInit() const
Get the initializer.
Definition DeclCXX.h:2578
SourceLocation getSourceLocation() const
Determine the source location of the initializer.
Definition DeclCXX.cpp:2921
bool isAnyMemberInitializer() const
Definition DeclCXX.h:2456
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
Definition DeclCXX.h:2448
bool isIndirectMemberInitializer() const
Definition DeclCXX.h:2460
const Type * getBaseClass() const
If this is a base class initializer, returns the type of the base class.
Definition DeclCXX.cpp:2914
FieldDecl * getAnyMember() const
Definition DeclCXX.h:2522
IndirectFieldDecl * getIndirectMember() const
Definition DeclCXX.h:2530
bool isBaseVirtual() const
Returns whether the base is virtual or not.
Definition DeclCXX.h:2502
Represents a C++ destructor within a class.
Definition DeclCXX.h:2876
const FunctionDecl * getOperatorDelete() const
Definition DeclCXX.cpp:3188
Expr * getOperatorDeleteThisArg() const
Definition DeclCXX.h:2915
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2136
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition DeclCXX.h:2262
QualType getThisType() const
Return the type of the this pointer.
Definition DeclCXX.cpp:2827
QualType getFunctionObjectParameterType() const
Definition DeclCXX.h:2286
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
Definition DeclCXX.cpp:2343
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
Definition DeclCXX.cpp:1679
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
Definition DeclCXX.h:1372
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
bool hasDefinition() const
Definition DeclCXX.h:561
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
Definition DeclCXX.cpp:1742
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:3746
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
static CharUnits One()
One - Construct a CharUnits quantity of one.
Definition CharUnits.h:58
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:3810
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:277
Represents a member of a struct/union/class.
Definition Decl.h:3175
Represents a function declaration or definition.
Definition Decl.h:2015
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
Definition Decl.cpp:4206
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition Decl.cpp:4194
bool isDestroyingOperatorDelete() const
Determine whether this is a destroying operator delete.
Definition Decl.cpp:3552
ArrayRef< ParmVarDecl * > parameters() const
Definition Decl.h:2789
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition Decl.h:2392
bool isVariadic() const
Whether this function is variadic.
Definition Decl.cpp:3134
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Definition Decl.cpp:4330
bool isDefaulted() const
Whether this function is defaulted.
Definition Decl.h:2400
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4550
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5357
bool isVariadic() const
Whether this function prototype is variadic.
Definition TypeBase.h:5761
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:4893
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:3482
ArrayRef< NamedDecl * > chain() const
Definition Decl.h:3503
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition TypeBase.h:3703
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
Definition Type.cpp:5534
QualType getPointeeType() const
Definition TypeBase.h:3721
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:1551
The collection of all-type qualifiers we support.
Definition TypeBase.h:331
field_range fields() const
Definition Decl.h:4545
Encodes a location in the source.
Stmt - This represents one statement.
Definition Stmt.h:86
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:343
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition Decl.h:3833
bool isUnion() const
Definition Decl.h:3943
A template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:3562
The base class of the type hierarchy.
Definition TypeBase.h:1866
CXXRecordDecl * castAsCXXRecordDecl() const
Definition Type.h:36
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9328
bool isRecordType() const
Definition TypeBase.h:8795
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 useEHCleanupForArray()
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