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(), "dynamic-length array expression");
743 }
744
745 // Tradional LLVM codegen emits a loop here. CIR lowers to a loop as part of
746 // LoweringPrepare.
747
748 // The alignment of the base, adjusted by the size of a single element,
749 // provides a conservative estimate of the alignment of every element.
750 // (This assumes we never start tracking offsetted alignments.)
751 //
752 // Note that these are complete objects and so we don't need to
753 // use the non-virtual size or alignment.
755 CharUnits eltAlignment = arrayBase.getAlignment().alignmentOfArrayElement(
756 getContext().getTypeSizeInChars(type));
757
758 // Zero initialize the storage, if requested.
759 if (zeroInitialize)
761
762 // C++ [class.temporary]p4:
763 // There are two contexts in which temporaries are destroyed at a different
764 // point than the end of the full-expression. The first context is when a
765 // default constructor is called to initialize an element of an array.
766 // If the constructor has one or more default arguments, the destruction of
767 // every temporary created in a default argument expression is sequenced
768 // before the construction of the next array element, if any.
769 {
770 RunCleanupsScope scope(*this);
771
772 // Evaluate the constructor and its arguments in a regular
773 // partial-destroy cleanup.
774 if (getLangOpts().Exceptions &&
775 !ctor->getParent()->hasTrivialDestructor()) {
776 cgm.errorNYI(e->getSourceRange(), "partial array cleanups");
777 }
778
779 // Emit the constructor call that will execute for every array element.
780 mlir::Value arrayOp =
781 builder.createPtrBitcast(arrayBase.getPointer(), arrayTy);
782 cir::ArrayCtor::create(
783 builder, *currSrcLoc, arrayOp,
784 [&](mlir::OpBuilder &b, mlir::Location loc) {
785 mlir::BlockArgument arg =
786 b.getInsertionBlock()->addArgument(ptrToElmType, loc);
787 Address curAddr = Address(arg, elementType, eltAlignment);
789 auto currAVS = AggValueSlot::forAddr(
790 curAddr, type.getQualifiers(), AggValueSlot::IsDestructed,
794 /*ForVirtualBase=*/false,
795 /*Delegating=*/false, currAVS, e);
796 cir::YieldOp::create(builder, loc);
797 });
798 }
799}
800
802 const CXXConstructorDecl *ctor, CXXCtorType ctorType,
803 const FunctionArgList &args, SourceLocation loc) {
804 CallArgList delegateArgs;
805
806 FunctionArgList::const_iterator i = args.begin(), e = args.end();
807 assert(i != e && "no parameters to constructor");
808
809 // this
810 Address thisAddr = loadCXXThisAddress();
811 delegateArgs.add(RValue::get(thisAddr.getPointer()), (*i)->getType());
812 ++i;
813
814 // FIXME: The location of the VTT parameter in the parameter list is specific
815 // to the Itanium ABI and shouldn't be hardcoded here.
816 if (cgm.getCXXABI().needsVTTParameter(curGD)) {
817 cgm.errorNYI(loc, "emitDelegateCXXConstructorCall: VTT parameter");
818 return;
819 }
820
821 // Explicit arguments.
822 for (; i != e; ++i) {
823 const VarDecl *param = *i;
824 // FIXME: per-argument source location
825 emitDelegateCallArg(delegateArgs, param, loc);
826 }
827
829
830 emitCXXConstructorCall(ctor, ctorType, /*ForVirtualBase=*/false,
831 /*Delegating=*/true, thisAddr, delegateArgs, loc);
832}
833
835 const auto *assignOp = cast<CXXMethodDecl>(curGD.getDecl());
836 assert(assignOp->isCopyAssignmentOperator() ||
837 assignOp->isMoveAssignmentOperator());
838 const Stmt *rootS = assignOp->getBody();
839 assert(isa<CompoundStmt>(rootS) &&
840 "Body of an implicit assignment operator should be compound stmt.");
841 const auto *rootCS = cast<CompoundStmt>(rootS);
842
843 cgm.setCXXSpecialMemberAttr(cast<cir::FuncOp>(curFn), assignOp);
844
847
848 // Classic codegen uses a special class to attempt to replace member
849 // initializers with memcpy. We could possibly defer that to the
850 // lowering or optimization phases to keep the memory accesses more
851 // explicit. For now, we don't insert memcpy at all, though in some
852 // cases the AST contains a call to memcpy.
854 for (Stmt *s : rootCS->body())
855 if (emitStmt(s, /*useCurrentScope=*/true).failed())
856 cgm.errorNYI(s->getSourceRange(),
857 std::string("emitImplicitAssignmentOperatorBody: ") +
858 s->getStmtClassName());
859}
860
862 const CXXMethodDecl *callOperator, CallArgList &callArgs) {
863 // Get the address of the call operator.
864 const CIRGenFunctionInfo &calleeFnInfo =
865 cgm.getTypes().arrangeCXXMethodDeclaration(callOperator);
866 cir::FuncOp calleePtr = cgm.getAddrOfFunction(
867 GlobalDecl(callOperator), cgm.getTypes().getFunctionType(calleeFnInfo));
868
869 // Prepare the return slot.
870 const FunctionProtoType *fpt =
871 callOperator->getType()->castAs<FunctionProtoType>();
872 QualType resultType = fpt->getReturnType();
873 ReturnValueSlot returnSlot;
874
875 // We don't need to separately arrange the call arguments because
876 // the call can't be variadic anyway --- it's impossible to forward
877 // variadic arguments.
878
879 // Now emit our call.
880 CIRGenCallee callee =
881 CIRGenCallee::forDirect(calleePtr, GlobalDecl(callOperator));
882 RValue rv = emitCall(calleeFnInfo, callee, returnSlot, callArgs);
883
884 // If necessary, copy the returned value into the slot.
885 if (!resultType->isVoidType() && returnSlot.isNull()) {
886 if (getLangOpts().ObjCAutoRefCount && resultType->isObjCRetainableType())
887 cgm.errorNYI(callOperator->getSourceRange(),
888 "emitForwardingCallToLambda: ObjCAutoRefCount");
889 emitReturnOfRValue(*currSrcLoc, rv, resultType);
890 } else {
891 cgm.errorNYI(callOperator->getSourceRange(),
892 "emitForwardingCallToLambda: return slot is not null");
893 }
894}
895
897 const CXXRecordDecl *lambda = md->getParent();
898
899 // Start building arguments for forwarding call
900 CallArgList callArgs;
901
902 QualType lambdaType = getContext().getCanonicalTagType(lambda);
903 QualType thisType = getContext().getPointerType(lambdaType);
904 Address thisPtr =
905 createMemTemp(lambdaType, getLoc(md->getSourceRange()), "unused.capture");
906 callArgs.add(RValue::get(thisPtr.getPointer()), thisType);
907
908 // Add the rest of the parameters.
909 for (auto *param : md->parameters())
910 emitDelegateCallArg(callArgs, param, param->getBeginLoc());
911
912 const CXXMethodDecl *callOp = lambda->getLambdaCallOperator();
913 // For a generic lambda, find the corresponding call operator specialization
914 // to which the call to the static-invoker shall be forwarded.
915 if (lambda->isGenericLambda()) {
918 FunctionTemplateDecl *callOpTemplate =
920 void *InsertPos = nullptr;
921 FunctionDecl *correspondingCallOpSpecialization =
922 callOpTemplate->findSpecialization(tal->asArray(), InsertPos);
923 assert(correspondingCallOpSpecialization);
924 callOp = cast<CXXMethodDecl>(correspondingCallOpSpecialization);
925 }
926 emitForwardingCallToLambda(callOp, callArgs);
927}
928
930 if (md->isVariadic()) {
931 // Codgen for LLVM doesn't emit code for this as well, it says:
932 // FIXME: Making this work correctly is nasty because it requires either
933 // cloning the body of the call operator or making the call operator
934 // forward.
935 cgm.errorNYI(md->getSourceRange(), "emitLambdaStaticInvokeBody: variadic");
936 }
937
939}
940
942 QualType type) {
943 const auto *record = type->castAsCXXRecordDecl();
944 const CXXDestructorDecl *dtor = record->getDestructor();
945 // TODO(cir): Unlike traditional codegen, CIRGen should actually emit trivial
946 // dtors which shall be removed on later CIR passes. However, only remove this
947 // assertion after we have a test case to exercise this path.
948 assert(!dtor->isTrivial());
949 cgf.emitCXXDestructorCall(dtor, Dtor_Complete, /*forVirtualBase*/ false,
950 /*delegating=*/false, addr, type);
951}
952
953namespace {
954mlir::Value loadThisForDtorDelete(CIRGenFunction &cgf,
955 const CXXDestructorDecl *dd) {
956 if (Expr *thisArg = dd->getOperatorDeleteThisArg())
957 return cgf.emitScalarExpr(thisArg);
958 return cgf.loadCXXThis();
959}
960
961/// Call the operator delete associated with the current destructor.
962struct CallDtorDelete final : EHScopeStack::Cleanup {
963 CallDtorDelete() {}
964
965 void emit(CIRGenFunction &cgf, Flags flags) override {
966 const CXXDestructorDecl *dtor = cast<CXXDestructorDecl>(cgf.curFuncDecl);
967 const CXXRecordDecl *classDecl = dtor->getParent();
969 loadThisForDtorDelete(cgf, dtor),
970 cgf.getContext().getCanonicalTagType(classDecl));
971 }
972};
973
974class DestroyField final : public EHScopeStack::Cleanup {
975 const FieldDecl *field;
976 CIRGenFunction::Destroyer *destroyer;
977
978public:
979 DestroyField(const FieldDecl *field, CIRGenFunction::Destroyer *destroyer)
980 : field(field), destroyer(destroyer) {}
981
982 void emit(CIRGenFunction &cgf, Flags flags) override {
983 // Find the address of the field.
984 Address thisValue = cgf.loadCXXThisAddress();
985 CanQualType recordTy =
986 cgf.getContext().getCanonicalTagType(field->getParent());
987 LValue thisLV = cgf.makeAddrLValue(thisValue, recordTy);
988 LValue lv = cgf.emitLValueForField(thisLV, field);
989 assert(lv.isSimple());
990
992 cgf.emitDestroy(lv.getAddress(), field->getType(), destroyer);
993 }
994};
995} // namespace
996
997/// Emit all code that comes at the end of class's destructor. This is to call
998/// destructors on members and base classes in reverse order of their
999/// construction.
1000///
1001/// For a deleting destructor, this also handles the case where a destroying
1002/// operator delete completely overrides the definition.
1004 CXXDtorType dtorType) {
1005 assert((!dd->isTrivial() || dd->hasAttr<DLLExportAttr>()) &&
1006 "Should not emit dtor epilogue for non-exported trivial dtor!");
1007
1008 // The deleting-destructor phase just needs to call the appropriate
1009 // operator delete that Sema picked up.
1010 if (dtorType == Dtor_Deleting) {
1011 assert(dd->getOperatorDelete() &&
1012 "operator delete missing - EnterDtorCleanups");
1014 cgm.errorNYI(dd->getSourceRange(), "deleting destructor with vtt");
1015 } else {
1017 cgm.errorNYI(dd->getSourceRange(),
1018 "deleting destructor with destroying operator delete");
1019 } else {
1020 ehStack.pushCleanup<CallDtorDelete>(NormalAndEHCleanup);
1021 }
1022 }
1023 return;
1024 }
1025
1026 const CXXRecordDecl *classDecl = dd->getParent();
1027
1028 // Unions have no bases and do not call field destructors.
1029 if (classDecl->isUnion())
1030 return;
1031
1032 // The complete-destructor phase just destructs all the virtual bases.
1033 if (dtorType == Dtor_Complete) {
1035
1036 // We push them in the forward order so that they'll be popped in
1037 // the reverse order.
1038 for (const CXXBaseSpecifier &base : classDecl->vbases()) {
1039 auto *baseClassDecl = base.getType()->castAsCXXRecordDecl();
1040
1041 if (baseClassDecl->hasTrivialDestructor()) {
1042 // Under SanitizeMemoryUseAfterDtor, poison the trivial base class
1043 // memory. For non-trival base classes the same is done in the class
1044 // destructor.
1046 } else {
1047 ehStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, baseClassDecl,
1048 /*baseIsVirtual=*/true);
1049 }
1050 }
1051
1052 return;
1053 }
1054
1055 assert(dtorType == Dtor_Base);
1057
1058 // Destroy non-virtual bases.
1059 for (const CXXBaseSpecifier &base : classDecl->bases()) {
1060 // Ignore virtual bases.
1061 if (base.isVirtual())
1062 continue;
1063
1064 CXXRecordDecl *baseClassDecl = base.getType()->getAsCXXRecordDecl();
1065
1066 if (baseClassDecl->hasTrivialDestructor())
1068 else
1069 ehStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, baseClassDecl,
1070 /*baseIsVirtual=*/false);
1071 }
1072
1074
1075 // Destroy direct fields.
1076 for (const FieldDecl *field : classDecl->fields()) {
1077 QualType type = field->getType();
1078 QualType::DestructionKind dtorKind = type.isDestructedType();
1079 if (!dtorKind)
1080 continue;
1081
1082 // Anonymous union members do not have their destructors called.
1083 const RecordType *rt = type->getAsUnionType();
1084 if (rt && rt->getDecl()->isAnonymousStructOrUnion())
1085 continue;
1086
1087 CleanupKind cleanupKind = getCleanupKind(dtorKind);
1089 ehStack.pushCleanup<DestroyField>(cleanupKind, field,
1090 getDestroyer(dtorKind));
1091 }
1092}
1093
1095 const CXXConstructorDecl *ctor, const FunctionArgList &args) {
1096 assert(ctor->isDelegatingConstructor());
1097
1098 Address thisPtr = loadCXXThisAddress();
1099
1106
1107 emitAggExpr(ctor->init_begin()[0]->getInit(), aggSlot);
1108
1109 const CXXRecordDecl *classDecl = ctor->getParent();
1110 if (cgm.getLangOpts().Exceptions && !classDecl->hasTrivialDestructor()) {
1111 cgm.errorNYI(ctor->getSourceRange(),
1112 "emitDelegatingCXXConstructorCall: exception");
1113 return;
1114 }
1115}
1116
1119 bool forVirtualBase, bool delegating,
1120 Address thisAddr, QualType thisTy) {
1121 cgm.getCXXABI().emitDestructorCall(*this, dd, type, forVirtualBase,
1122 delegating, thisAddr, thisTy);
1123}
1124
1125mlir::Value CIRGenFunction::getVTTParameter(GlobalDecl gd, bool forVirtualBase,
1126 bool delegating) {
1127 if (!cgm.getCXXABI().needsVTTParameter(gd))
1128 return nullptr;
1129
1130 const CXXRecordDecl *rd = cast<CXXMethodDecl>(curCodeDecl)->getParent();
1131 const CXXRecordDecl *base = cast<CXXMethodDecl>(gd.getDecl())->getParent();
1132
1133 uint64_t subVTTIndex;
1134
1135 if (delegating) {
1136 // If this is a delegating constructor call, just load the VTT.
1137 return loadCXXVTT();
1138 } else if (rd == base) {
1139 // If the record matches the base, this is the complete ctor/dtor
1140 // variant calling the base variant in a class with virtual bases.
1141 assert(!cgm.getCXXABI().needsVTTParameter(curGD) &&
1142 "doing no-op VTT offset in base dtor/ctor?");
1143 assert(!forVirtualBase && "Can't have same class as virtual base!");
1144 subVTTIndex = 0;
1145 } else {
1146 const ASTRecordLayout &layout = getContext().getASTRecordLayout(rd);
1147 CharUnits baseOffset = forVirtualBase ? layout.getVBaseClassOffset(base)
1148 : layout.getBaseClassOffset(base);
1149
1150 subVTTIndex =
1151 cgm.getVTables().getSubVTTIndex(rd, BaseSubobject(base, baseOffset));
1152 assert(subVTTIndex != 0 && "Sub-VTT index must be greater than zero!");
1153 }
1154
1155 mlir::Location loc = cgm.getLoc(rd->getBeginLoc());
1156 if (cgm.getCXXABI().needsVTTParameter(curGD)) {
1157 // A VTT parameter was passed to the constructor, use it.
1158 mlir::Value vtt = loadCXXVTT();
1159 return builder.createVTTAddrPoint(loc, vtt.getType(), vtt, subVTTIndex);
1160 } else {
1161 // We're the complete constructor, so get the VTT by name.
1162 cir::GlobalOp vtt = cgm.getVTables().getAddrOfVTT(rd);
1163 return builder.createVTTAddrPoint(
1164 loc, builder.getPointerTo(cgm.voidPtrTy),
1165 mlir::FlatSymbolRefAttr::get(vtt.getSymNameAttr()), subVTTIndex);
1166 }
1167}
1168
1170 mlir::Location loc, Address baseAddr, const CXXRecordDecl *derived,
1171 llvm::iterator_range<CastExpr::path_const_iterator> path,
1172 bool nullCheckValue) {
1173 assert(!path.empty() && "Base path should not be empty!");
1174
1175 QualType derivedTy = getContext().getCanonicalTagType(derived);
1176 mlir::Type derivedValueTy = convertType(derivedTy);
1177 CharUnits nonVirtualOffset =
1178 cgm.computeNonVirtualBaseClassOffset(derived, path);
1179
1180 // Note that in OG, no offset (nonVirtualOffset.getQuantity() == 0) means it
1181 // just gives the address back. In CIR a `cir.derived_class` is created and
1182 // made into a nop later on during lowering.
1183 return builder.createDerivedClassAddr(loc, baseAddr, derivedValueTy,
1184 nonVirtualOffset.getQuantity(),
1185 /*assumeNotNull=*/!nullCheckValue);
1186}
1187
1189 Address value, const CXXRecordDecl *derived,
1190 llvm::iterator_range<CastExpr::path_const_iterator> path,
1191 bool nullCheckValue, SourceLocation loc) {
1192 assert(!path.empty() && "Base path should not be empty!");
1193
1194 CastExpr::path_const_iterator start = path.begin();
1195 const CXXRecordDecl *vBase = nullptr;
1196
1197 if ((*path.begin())->isVirtual()) {
1198 vBase = (*start)->getType()->castAsCXXRecordDecl();
1199 ++start;
1200 }
1201
1202 // Compute the static offset of the ultimate destination within its
1203 // allocating subobject (the virtual base, if there is one, or else
1204 // the "complete" object that we see).
1205 CharUnits nonVirtualOffset = cgm.computeNonVirtualBaseClassOffset(
1206 vBase ? vBase : derived, {start, path.end()});
1207
1208 // If there's a virtual step, we can sometimes "devirtualize" it.
1209 // For now, that's limited to when the derived type is final.
1210 // TODO: "devirtualize" this for accesses to known-complete objects.
1211 if (vBase && derived->hasAttr<FinalAttr>()) {
1212 const ASTRecordLayout &layout = getContext().getASTRecordLayout(derived);
1213 CharUnits vBaseOffset = layout.getVBaseClassOffset(vBase);
1214 nonVirtualOffset += vBaseOffset;
1215 vBase = nullptr; // we no longer have a virtual step
1216 }
1217
1218 // Get the base pointer type.
1219 mlir::Type baseValueTy = convertType((path.end()[-1])->getType());
1221
1222 // If there is no virtual base, use cir.base_class_addr. It takes care of
1223 // the adjustment and the null pointer check.
1224 if (nonVirtualOffset.isZero() && !vBase) {
1226 return builder.createBaseClassAddr(getLoc(loc), value, baseValueTy, 0,
1227 /*assumeNotNull=*/true);
1228 }
1229
1231
1232 // Compute the virtual offset.
1233 mlir::Value virtualOffset = nullptr;
1234 if (vBase) {
1235 virtualOffset = cgm.getCXXABI().getVirtualBaseClassOffset(
1236 getLoc(loc), *this, value, derived, vBase);
1237 }
1238
1239 // Apply both offsets.
1241 getLoc(loc), *this, value, nonVirtualOffset, virtualOffset, derived,
1242 vBase, baseValueTy, not nullCheckValue);
1243
1244 // Cast to the destination type.
1245 value = value.withElementType(builder, baseValueTy);
1246
1247 return value;
1248}
1249
1250// TODO(cir): this can be shared with LLVM codegen.
1253 if (!cgm.getCodeGenOpts().WholeProgramVTables)
1254 return false;
1255
1256 if (cgm.getCodeGenOpts().VirtualFunctionElimination)
1257 return true;
1258
1260
1261 return false;
1262}
1263
1264mlir::Value CIRGenFunction::getVTablePtr(mlir::Location loc, Address thisAddr,
1265 const CXXRecordDecl *rd) {
1266 auto vtablePtr =
1267 cir::VTableGetVPtrOp::create(builder, loc, thisAddr.getPointer());
1268 Address vtablePtrAddr = Address(vtablePtr, thisAddr.getAlignment());
1269
1270 auto vtable = builder.createLoad(loc, vtablePtrAddr);
1272
1273 if (cgm.getCodeGenOpts().OptimizationLevel > 0 &&
1274 cgm.getCodeGenOpts().StrictVTablePointers) {
1276 }
1277
1278 return vtable;
1279}
1280
1283 bool forVirtualBase,
1284 bool delegating,
1285 AggValueSlot thisAVS,
1286 const clang::CXXConstructExpr *e) {
1287 CallArgList args;
1288 Address thisAddr = thisAVS.getAddress();
1289 QualType thisType = d->getThisType();
1290 mlir::Value thisPtr = thisAddr.getPointer();
1291
1293
1294 args.add(RValue::get(thisPtr), thisType);
1295
1296 // In LLVM Codegen: If this is a trivial constructor, just emit what's needed.
1297 // If this is a union copy constructor, we must emit a memcpy, because the AST
1298 // does not model that copy.
1300
1301 const FunctionProtoType *fpt = d->getType()->castAs<FunctionProtoType>();
1302
1304
1305 emitCallArgs(args, fpt, e->arguments(), e->getConstructor(),
1306 /*ParamsToSkip=*/0);
1307
1309 emitCXXConstructorCall(d, type, forVirtualBase, delegating, thisAddr, args,
1310 e->getExprLoc());
1311}
1312
1314 const CXXConstructorDecl *d, CXXCtorType type, bool forVirtualBase,
1315 bool delegating, Address thisAddr, CallArgList &args, SourceLocation loc) {
1316
1317 const CXXRecordDecl *crd = d->getParent();
1318
1319 // If this is a call to a trivial default constructor:
1320 // In LLVM: do nothing.
1321 // In CIR: emit as a regular call, other later passes should lower the
1322 // ctor call into trivial initialization.
1324
1326
1327 bool passPrototypeArgs = true;
1328
1329 // Check whether we can actually emit the constructor before trying to do so.
1330 if (d->getInheritedConstructor()) {
1331 cgm.errorNYI(d->getSourceRange(),
1332 "emitCXXConstructorCall: inherited constructor");
1333 return;
1334 }
1335
1336 // Insert any ABI-specific implicit constructor arguments.
1338 cgm.getCXXABI().addImplicitConstructorArgs(*this, d, type, forVirtualBase,
1339 delegating, args);
1340
1341 // Emit the call.
1342 auto calleePtr = cgm.getAddrOfCXXStructor(GlobalDecl(d, type));
1343 const CIRGenFunctionInfo &info = cgm.getTypes().arrangeCXXConstructorCall(
1344 args, d, type, extraArgs.prefix, extraArgs.suffix, passPrototypeArgs);
1345 CIRGenCallee callee = CIRGenCallee::forDirect(calleePtr, GlobalDecl(d, type));
1346 cir::CIRCallOpInterface c;
1347 emitCall(info, callee, ReturnValueSlot(), args, &c, getLoc(loc));
1348
1349 if (cgm.getCodeGenOpts().OptimizationLevel != 0 && !crd->isDynamicClass() &&
1350 type != Ctor_Base && cgm.getCodeGenOpts().StrictVTablePointers)
1351 cgm.errorNYI(d->getSourceRange(), "vtable assumption loads");
1352}
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:3730
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:3768
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: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: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: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: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:2385
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:5315
bool isVariadic() const
Whether this function prototype is variadic.
Definition TypeBase.h:5719
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:4851
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
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition TypeBase.h:3661
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
Definition Type.cpp:5530
QualType getPointeeType() const
Definition TypeBase.h:3679
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:4530
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:3818
bool isUnion() const
Definition Decl.h:3928
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:1839
CXXRecordDecl * castAsCXXRecordDecl() const
Definition Type.h:36
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9285
bool isRecordType() const
Definition TypeBase.h:8752
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