clang 22.0.0git
CIRGenClass.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This contains code dealing with C++ code generation of classes
10//
11//===----------------------------------------------------------------------===//
12
13#include "CIRGenCXXABI.h"
14#include "CIRGenFunction.h"
15#include "CIRGenValue.h"
16
18#include "clang/AST/ExprCXX.h"
20#include "clang/AST/Type.h"
22
23using namespace clang;
24using namespace clang::CIRGen;
25
26/// Checks whether the given constructor is a valid subject for the
27/// complete-to-base constructor delegation optimization, i.e. emitting the
28/// complete constructor as a simple call to the base constructor.
30 const CXXConstructorDecl *ctor) {
31 // Currently we disable the optimization for classes with virtual bases
32 // because (1) the address of parameter variables need to be consistent across
33 // all initializers but (2) the delegate function call necessarily creates a
34 // second copy of the parameter variable.
35 //
36 // The limiting example (purely theoretical AFAIK):
37 // struct A { A(int &c) { c++; } };
38 // struct A : virtual A {
39 // B(int count) : A(count) { printf("%d\n", count); }
40 // };
41 // ...although even this example could in principle be emitted as a delegation
42 // since the address of the parameter doesn't escape.
43 if (ctor->getParent()->getNumVBases())
44 return false;
45
46 // We also disable the optimization for variadic functions because it's
47 // impossible to "re-pass" varargs.
48 if (ctor->getType()->castAs<FunctionProtoType>()->isVariadic())
49 return false;
50
51 // FIXME: Decide if we can do a delegation of a delegating constructor.
52 if (ctor->isDelegatingConstructor())
53 return false;
54
55 return true;
56}
57
59 CXXCtorInitializer *memberInit,
60 LValue &lhs) {
61 FieldDecl *field = memberInit->getAnyMember();
62 if (memberInit->isIndirectMemberInitializer()) {
63 // If we are initializing an anonymous union field, drill down to the field.
64 IndirectFieldDecl *indirectField = memberInit->getIndirectMember();
65 for (const auto *nd : indirectField->chain()) {
66 auto *fd = cast<clang::FieldDecl>(nd);
67 lhs = cgf.emitLValueForFieldInitialization(lhs, fd, fd->getName());
68 }
69 } else {
70 lhs = cgf.emitLValueForFieldInitialization(lhs, field, field->getName());
71 }
72}
73
75 const CXXRecordDecl *classDecl,
76 CXXCtorInitializer *memberInit,
77 const CXXConstructorDecl *constructor,
78 FunctionArgList &args) {
79 assert(memberInit->isAnyMemberInitializer() &&
80 "Must have member initializer!");
81 assert(memberInit->getInit() && "Must have initializer!");
82
84
85 // non-static data member initializers
86 FieldDecl *field = memberInit->getAnyMember();
87 QualType fieldType = field->getType();
88
89 mlir::Value thisPtr = cgf.loadCXXThis();
90 CanQualType recordTy = cgf.getContext().getCanonicalTagType(classDecl);
91
92 // If a base constructor is being emitted, create an LValue that has the
93 // non-virtual alignment.
94 LValue lhs = (cgf.curGD.getCtorType() == Ctor_Base)
95 ? cgf.makeNaturalAlignPointeeAddrLValue(thisPtr, recordTy)
96 : cgf.makeNaturalAlignAddrLValue(thisPtr, recordTy);
97
98 emitLValueForAnyFieldInitialization(cgf, memberInit, lhs);
99
100 // Special case: If we are in a copy or move constructor, and we are copying
101 // an array off PODs or classes with trivial copy constructors, ignore the AST
102 // and perform the copy we know is equivalent.
103 // FIXME: This is hacky at best... if we had a bit more explicit information
104 // in the AST, we could generalize it more easily.
105 const ConstantArrayType *array =
106 cgf.getContext().getAsConstantArrayType(fieldType);
107 if (array && constructor->isDefaulted() &&
108 constructor->isCopyOrMoveConstructor()) {
109 QualType baseElementTy = cgf.getContext().getBaseElementType(array);
110 // NOTE(cir): CodeGen allows record types to be memcpy'd if applicable,
111 // whereas ClangIR wants to represent all object construction explicitly.
112 if (!baseElementTy->isRecordType()) {
113 cgf.cgm.errorNYI(memberInit->getSourceRange(),
114 "emitMemberInitializer: array of non-record type");
115 return;
116 }
117 }
118
119 cgf.emitInitializerForField(field, lhs, memberInit->getInit());
120}
121
123 const Type *baseType = baseInit->getBaseClass();
124 const auto *baseClassDecl = baseType->castAsCXXRecordDecl();
125 return baseClassDecl->isDynamicClass();
126}
127
128namespace {
129/// A visitor which checks whether an initializer uses 'this' in a
130/// way which requires the vtable to be properly set.
131struct DynamicThisUseChecker
132 : ConstEvaluatedExprVisitor<DynamicThisUseChecker> {
134
135 bool usesThis = false;
136
137 DynamicThisUseChecker(const ASTContext &c) : super(c) {}
138
139 // Black-list all explicit and implicit references to 'this'.
140 //
141 // Do we need to worry about external references to 'this' derived
142 // from arbitrary code? If so, then anything which runs arbitrary
143 // external code might potentially access the vtable.
144 void VisitCXXThisExpr(const CXXThisExpr *e) { usesThis = true; }
145};
146} // end anonymous namespace
147
148static bool baseInitializerUsesThis(ASTContext &c, const Expr *init) {
149 DynamicThisUseChecker checker(c);
150 checker.Visit(init);
151 return checker.usesThis;
152}
153
154/// Gets the address of a direct base class within a complete object.
155/// This should only be used for (1) non-virtual bases or (2) virtual bases
156/// when the type is known to be complete (e.g. in complete destructors).
157///
158/// The object pointed to by 'thisAddr' is assumed to be non-null.
160 mlir::Location loc, Address thisAddr, const CXXRecordDecl *derived,
161 const CXXRecordDecl *base, bool baseIsVirtual) {
162 // 'thisAddr' must be a pointer (in some address space) to Derived.
163 assert(thisAddr.getElementType() == convertType(derived));
164
165 // Compute the offset of the virtual base.
166 CharUnits offset;
167 const ASTRecordLayout &layout = getContext().getASTRecordLayout(derived);
168 if (baseIsVirtual)
169 offset = layout.getVBaseClassOffset(base);
170 else
171 offset = layout.getBaseClassOffset(base);
172
173 return builder.createBaseClassAddr(loc, thisAddr, convertType(base),
174 offset.getQuantity(),
175 /*assumeNotNull=*/true);
176}
177
179 const CXXRecordDecl *classDecl,
180 CXXCtorInitializer *baseInit) {
181 assert(curFuncDecl && "loading 'this' without a func declaration?");
182 assert(isa<CXXMethodDecl>(curFuncDecl));
183
184 assert(baseInit->isBaseInitializer() && "Must have base initializer!");
185
186 Address thisPtr = loadCXXThisAddress();
187
188 const Type *baseType = baseInit->getBaseClass();
189 const auto *baseClassDecl = baseType->castAsCXXRecordDecl();
190
191 bool isBaseVirtual = baseInit->isBaseVirtual();
192
193 // If the initializer for the base (other than the constructor
194 // itself) accesses 'this' in any way, we need to initialize the
195 // vtables.
196 if (baseInitializerUsesThis(getContext(), baseInit->getInit()))
197 initializeVTablePointers(loc, classDecl);
198
199 // We can pretend to be a complete class because it only matters for
200 // virtual bases, and we only do virtual bases for complete ctors.
202 loc, thisPtr, classDecl, baseClassDecl, isBaseVirtual);
206 getOverlapForBaseInit(classDecl, baseClassDecl, isBaseVirtual));
207
208 emitAggExpr(baseInit->getInit(), aggSlot);
209
211}
212
213/// This routine generates necessary code to initialize base classes and
214/// non-static data members belonging to this constructor.
216 CXXCtorType ctorType,
217 FunctionArgList &args) {
218 if (cd->isDelegatingConstructor()) {
220 return;
221 }
222
223 const CXXRecordDecl *classDecl = cd->getParent();
224
225 // Virtual base initializers aren't needed if:
226 // - This is a base ctor variant
227 // - There are no vbases
228 // - The class is abstract, so a complete object of it cannot be constructed
229 //
230 // The check for an abstract class is necessary because sema may not have
231 // marked virtual base destructors referenced.
232 bool constructVBases = ctorType != Ctor_Base &&
233 classDecl->getNumVBases() != 0 &&
234 !classDecl->isAbstract();
235 if (constructVBases &&
238 "emitCtorPrologue: virtual base without variants");
239 return;
240 }
241
242 // Create three separate ranges for the different types of initializers.
243 auto allInits = cd->inits();
244
245 // Find the boundaries between the three groups.
246 auto virtualBaseEnd = std::find_if(
247 allInits.begin(), allInits.end(), [](const CXXCtorInitializer *Init) {
248 return !(Init->isBaseInitializer() && Init->isBaseVirtual());
249 });
250
251 auto nonVirtualBaseEnd = std::find_if(virtualBaseEnd, allInits.end(),
252 [](const CXXCtorInitializer *Init) {
253 return !Init->isBaseInitializer();
254 });
255
256 // Create the three ranges.
257 auto virtualBaseInits = llvm::make_range(allInits.begin(), virtualBaseEnd);
258 auto nonVirtualBaseInits =
259 llvm::make_range(virtualBaseEnd, nonVirtualBaseEnd);
260 auto memberInits = llvm::make_range(nonVirtualBaseEnd, allInits.end());
261
262 const mlir::Value oldThisValue = cxxThisValue;
263
264 auto emitInitializer = [&](CXXCtorInitializer *baseInit) {
265 if (cgm.getCodeGenOpts().StrictVTablePointers &&
266 cgm.getCodeGenOpts().OptimizationLevel > 0 &&
267 isInitializerOfDynamicClass(baseInit)) {
268 // It's OK to continue after emitting the error here. The missing code
269 // just "launders" the 'this' pointer.
271 "emitCtorPrologue: strict vtable pointers for vbase");
272 }
273 emitBaseInitializer(getLoc(cd->getBeginLoc()), classDecl, baseInit);
274 };
275
276 // Process virtual base initializers.
277 for (CXXCtorInitializer *virtualBaseInit : virtualBaseInits) {
278 if (!constructVBases)
279 continue;
280 emitInitializer(virtualBaseInit);
281 }
282
284
285 // Then, non-virtual base initializers.
286 for (CXXCtorInitializer *nonVirtualBaseInit : nonVirtualBaseInits) {
287 assert(!nonVirtualBaseInit->isBaseVirtual());
288 emitInitializer(nonVirtualBaseInit);
289 }
290
291 cxxThisValue = oldThisValue;
292
294
295 // Finally, initialize class members.
297 // Classic codegen uses a special class to attempt to replace member
298 // initializers with memcpy. We could possibly defer that to the
299 // lowering or optimization phases to keep the memory accesses more
300 // explicit. For now, we don't insert memcpy at all.
302 for (CXXCtorInitializer *member : memberInits) {
303 assert(!member->isBaseInitializer());
304 assert(member->isAnyMemberInitializer() &&
305 "Delegating initializer on non-delegating constructor");
306 emitMemberInitializer(*this, cd->getParent(), member, cd, args);
307 }
308}
309
311 mlir::Location loc, CIRGenFunction &cgf, Address addr,
312 CharUnits nonVirtualOffset, mlir::Value virtualOffset,
313 const CXXRecordDecl *derivedClass, const CXXRecordDecl *nearestVBase,
314 mlir::Type baseValueTy = {}, bool assumeNotNull = true) {
315 // Assert that we have something to do.
316 assert(!nonVirtualOffset.isZero() || virtualOffset != nullptr);
317
318 // Compute the offset from the static and dynamic components.
319 if (!nonVirtualOffset.isZero()) {
320 if (virtualOffset) {
321 cgf.cgm.errorNYI(
322 loc,
323 "applyNonVirtualAndVirtualOffset: virtual and non-virtual offset");
324 return Address::invalid();
325 } else {
326 assert(baseValueTy && "expected base type");
327 // If no virtualOffset is present this is the final stop.
328 return cgf.getBuilder().createBaseClassAddr(
329 loc, addr, baseValueTy, nonVirtualOffset.getQuantity(),
330 assumeNotNull);
331 }
332 }
333
334 cgf.cgm.errorNYI(loc, "applyNonVirtualAndVirtualOffset: virtual offset");
335 return Address::invalid();
336}
337
339 const VPtr &vptr) {
340 // Compute the address point.
341 mlir::Value vtableAddressPoint =
343 *this, vptr.vtableClass, vptr.base, vptr.nearestVBase);
344
345 if (!vtableAddressPoint)
346 return;
347
348 // Compute where to store the address point.
349 mlir::Value virtualOffset{};
350 CharUnits nonVirtualOffset = CharUnits::Zero();
351
352 mlir::Type baseValueTy;
354 cgm.errorNYI(loc, "initializeVTablePointer: virtual offset for vtable");
355 } else {
356 // We can just use the base offset in the complete class.
357 nonVirtualOffset = vptr.base.getBaseOffset();
358 baseValueTy =
359 convertType(getContext().getCanonicalTagType(vptr.base.getBase()));
360 }
361
362 // Apply the offsets.
363 Address classAddr = loadCXXThisAddress();
364 if (!nonVirtualOffset.isZero() || virtualOffset) {
366 loc, *this, classAddr, nonVirtualOffset, virtualOffset,
367 vptr.vtableClass, vptr.nearestVBase, baseValueTy);
368 }
369
370 // Finally, store the address point. Use the same CIR types as the field.
371 //
372 // vtable field is derived from `this` pointer, therefore they should be in
373 // the same addr space.
375 auto vtablePtr = cir::VTableGetVPtrOp::create(
376 builder, loc, builder.getPtrToVPtrType(), classAddr.getPointer());
377 Address vtableField = Address(vtablePtr, classAddr.getAlignment());
378 builder.createStore(loc, vtableAddressPoint, vtableField);
381}
382
384 const CXXRecordDecl *rd) {
385 // Ignore classes without a vtable.
386 if (!rd->isDynamicClass())
387 return;
388
389 // Initialize the vtable pointers for this class and all of its bases.
391 for (const auto &vptr : getVTablePointers(rd))
392 initializeVTablePointer(loc, vptr);
393
394 if (rd->getNumVBases())
396}
397
400 CIRGenFunction::VPtrsVector vptrsResult;
403 /*NearestVBase=*/nullptr,
404 /*OffsetFromNearestVBase=*/CharUnits::Zero(),
405 /*BaseIsNonVirtualPrimaryBase=*/false, vtableClass, vbases,
406 vptrsResult);
407 return vptrsResult;
408}
409
411 const CXXRecordDecl *nearestVBase,
412 CharUnits offsetFromNearestVBase,
413 bool baseIsNonVirtualPrimaryBase,
414 const CXXRecordDecl *vtableClass,
416 VPtrsVector &vptrs) {
417 // If this base is a non-virtual primary base the address point has already
418 // been set.
419 if (!baseIsNonVirtualPrimaryBase) {
420 // Initialize the vtable pointer for this base.
421 VPtr vptr = {base, nearestVBase, offsetFromNearestVBase, vtableClass};
422 vptrs.push_back(vptr);
423 }
424
425 const CXXRecordDecl *rd = base.getBase();
426
427 for (const auto &nextBase : rd->bases()) {
428 const auto *baseDecl =
429 cast<CXXRecordDecl>(
430 nextBase.getType()->castAs<RecordType>()->getOriginalDecl())
432
433 // Ignore classes without a vtable.
434 if (!baseDecl->isDynamicClass())
435 continue;
436
437 CharUnits baseOffset;
438 CharUnits baseOffsetFromNearestVBase;
439 bool baseDeclIsNonVirtualPrimaryBase;
440 const CXXRecordDecl *nextBaseDecl;
441
442 if (nextBase.isVirtual()) {
443 // Check if we've visited this virtual base before.
444 if (!vbases.insert(baseDecl).second)
445 continue;
446
447 const ASTRecordLayout &layout =
448 getContext().getASTRecordLayout(vtableClass);
449
450 nextBaseDecl = nearestVBase;
451 baseOffset = layout.getVBaseClassOffset(baseDecl);
452 baseOffsetFromNearestVBase = CharUnits::Zero();
453 baseDeclIsNonVirtualPrimaryBase = false;
454 } else {
455 const ASTRecordLayout &layout = getContext().getASTRecordLayout(rd);
456
457 nextBaseDecl = baseDecl;
458 baseOffset = base.getBaseOffset() + layout.getBaseClassOffset(baseDecl);
459 baseOffsetFromNearestVBase =
460 offsetFromNearestVBase + layout.getBaseClassOffset(baseDecl);
461 baseDeclIsNonVirtualPrimaryBase = layout.getPrimaryBase() == baseDecl;
462 }
463
464 getVTablePointers(BaseSubobject(baseDecl, baseOffset), nextBaseDecl,
465 baseOffsetFromNearestVBase,
466 baseDeclIsNonVirtualPrimaryBase, vtableClass, vbases,
467 vptrs);
468 }
469}
470
472 assert(curFuncDecl && "loading 'this' without a func declaration?");
473 assert(isa<CXXMethodDecl>(curFuncDecl));
474
475 // Lazily compute CXXThisAlignment.
476 if (cxxThisAlignment.isZero()) {
477 // Just use the best known alignment for the parent.
478 // TODO: if we're currently emitting a complete-object ctor/dtor, we can
479 // always use the complete-object alignment.
480 auto rd = cast<CXXMethodDecl>(curFuncDecl)->getParent();
482 }
483
485}
486
488 Expr *init) {
489 QualType fieldType = field->getType();
490 switch (getEvaluationKind(fieldType)) {
491 case cir::TEK_Scalar:
492 if (lhs.isSimple())
493 emitExprAsInit(init, field, lhs, false);
494 else
495 cgm.errorNYI(field->getSourceRange(),
496 "emitInitializerForField: non-simple scalar");
497 break;
498 case cir::TEK_Complex:
499 cgm.errorNYI(field->getSourceRange(), "emitInitializerForField: complex");
500 break;
501 case cir::TEK_Aggregate: {
502 cgm.errorNYI(field->getSourceRange(), "emitInitializerForField: aggregate");
503 break;
504 }
505 }
506
507 // Ensure that we destroy this object if an exception is thrown later in the
508 // constructor.
509 QualType::DestructionKind dtorKind = fieldType.isDestructedType();
510 (void)dtorKind;
512}
513
514/// Emit a loop to call a particular constructor for each of several members
515/// of an array.
516///
517/// \param ctor the constructor to call for each element
518/// \param arrayType the type of the array to initialize
519/// \param arrayBegin an arrayType*
520/// \param zeroInitialize true if each element should be
521/// zero-initialized before it is constructed
524 Address arrayBegin, const CXXConstructExpr *e, bool newPointerIsChecked,
525 bool zeroInitialize) {
526 QualType elementType;
527 mlir::Value numElements = emitArrayLength(arrayType, elementType, arrayBegin);
528 emitCXXAggrConstructorCall(ctor, numElements, arrayBegin, e,
529 newPointerIsChecked, zeroInitialize);
530}
531
532/// Emit a loop to call a particular constructor for each of several members
533/// of an array.
534///
535/// \param ctor the constructor to call for each element
536/// \param numElements the number of elements in the array;
537/// may be zero
538/// \param arrayBase a T*, where T is the type constructed by ctor
539/// \param zeroInitialize true if each element should be
540/// zero-initialized before it is constructed
542 const CXXConstructorDecl *ctor, mlir::Value numElements, Address arrayBase,
543 const CXXConstructExpr *e, bool newPointerIsChecked, bool zeroInitialize) {
544 // It's legal for numElements to be zero. This can happen both
545 // dynamically, because x can be zero in 'new A[x]', and statically,
546 // because of GCC extensions that permit zero-length arrays. There
547 // are probably legitimate places where we could assume that this
548 // doesn't happen, but it's not clear that it's worth it.
549
550 // Optimize for a constant count.
551 if (auto constantCount = numElements.getDefiningOp<cir::ConstantOp>()) {
552 if (auto constIntAttr = constantCount.getValueAttr<cir::IntAttr>()) {
553 // Just skip out if the constant count is zero.
554 if (constIntAttr.getUInt() == 0)
555 return;
556 // Otherwise, emit the check.
557 }
558
559 if (constantCount.use_empty())
560 constantCount.erase();
561 } else {
562 // Otherwise, emit the check.
563 cgm.errorNYI(e->getSourceRange(), "dynamic-length array expression");
564 }
565
566 auto arrayTy = mlir::cast<cir::ArrayType>(arrayBase.getElementType());
567 mlir::Type elementType = arrayTy.getElementType();
568 cir::PointerType ptrToElmType = builder.getPointerTo(elementType);
569
570 // Tradional LLVM codegen emits a loop here. CIR lowers to a loop as part of
571 // LoweringPrepare.
572
573 // The alignment of the base, adjusted by the size of a single element,
574 // provides a conservative estimate of the alignment of every element.
575 // (This assumes we never start tracking offsetted alignments.)
576 //
577 // Note that these are complete objects and so we don't need to
578 // use the non-virtual size or alignment.
580 CharUnits eltAlignment = arrayBase.getAlignment().alignmentOfArrayElement(
581 getContext().getTypeSizeInChars(type));
582
583 // Zero initialize the storage, if requested.
584 if (zeroInitialize)
586
587 // C++ [class.temporary]p4:
588 // There are two contexts in which temporaries are destroyed at a different
589 // point than the end of the full-expression. The first context is when a
590 // default constructor is called to initialize an element of an array.
591 // If the constructor has one or more default arguments, the destruction of
592 // every temporary created in a default argument expression is sequenced
593 // before the construction of the next array element, if any.
594 {
596
597 // Evaluate the constructor and its arguments in a regular
598 // partial-destroy cleanup.
599 if (getLangOpts().Exceptions &&
600 !ctor->getParent()->hasTrivialDestructor()) {
601 cgm.errorNYI(e->getSourceRange(), "partial array cleanups");
602 }
603
604 // Emit the constructor call that will execute for every array element.
605 mlir::Value arrayOp =
606 builder.createPtrBitcast(arrayBase.getPointer(), arrayTy);
607 builder.create<cir::ArrayCtor>(
608 *currSrcLoc, arrayOp, [&](mlir::OpBuilder &b, mlir::Location loc) {
609 mlir::BlockArgument arg =
610 b.getInsertionBlock()->addArgument(ptrToElmType, loc);
611 Address curAddr = Address(arg, elementType, eltAlignment);
613 auto currAVS = AggValueSlot::forAddr(
614 curAddr, type.getQualifiers(), AggValueSlot::IsDestructed,
618 /*ForVirtualBase=*/false,
619 /*Delegating=*/false, currAVS, e);
620 builder.create<cir::YieldOp>(loc);
621 });
622 }
623}
624
626 const CXXConstructorDecl *ctor, CXXCtorType ctorType,
627 const FunctionArgList &args, SourceLocation loc) {
628 CallArgList delegateArgs;
629
630 FunctionArgList::const_iterator i = args.begin(), e = args.end();
631 assert(i != e && "no parameters to constructor");
632
633 // this
634 Address thisAddr = loadCXXThisAddress();
635 delegateArgs.add(RValue::get(thisAddr.getPointer()), (*i)->getType());
636 ++i;
637
638 // FIXME: The location of the VTT parameter in the parameter list is specific
639 // to the Itanium ABI and shouldn't be hardcoded here.
641 cgm.errorNYI(loc, "emitDelegateCXXConstructorCall: VTT parameter");
642 return;
643 }
644
645 // Explicit arguments.
646 for (; i != e; ++i) {
647 const VarDecl *param = *i;
648 // FIXME: per-argument source location
649 emitDelegateCallArg(delegateArgs, param, loc);
650 }
651
653
654 emitCXXConstructorCall(ctor, ctorType, /*ForVirtualBase=*/false,
655 /*Delegating=*/true, thisAddr, delegateArgs, loc);
656}
657
659 const auto *assignOp = cast<CXXMethodDecl>(curGD.getDecl());
660 assert(assignOp->isCopyAssignmentOperator() ||
661 assignOp->isMoveAssignmentOperator());
662 const Stmt *rootS = assignOp->getBody();
663 assert(isa<CompoundStmt>(rootS) &&
664 "Body of an implicit assignment operator should be compound stmt.");
665 const auto *rootCS = cast<CompoundStmt>(rootS);
666
669
670 // Classic codegen uses a special class to attempt to replace member
671 // initializers with memcpy. We could possibly defer that to the
672 // lowering or optimization phases to keep the memory accesses more
673 // explicit. For now, we don't insert memcpy at all, though in some
674 // cases the AST contains a call to memcpy.
676 for (Stmt *s : rootCS->body())
677 if (emitStmt(s, /*useCurrentScope=*/true).failed())
678 cgm.errorNYI(s->getSourceRange(),
679 std::string("emitImplicitAssignmentOperatorBody: ") +
680 s->getStmtClassName());
681}
682
684 QualType type) {
685 const auto *record = type->castAsCXXRecordDecl();
686 const CXXDestructorDecl *dtor = record->getDestructor();
687 // TODO(cir): Unlike traditional codegen, CIRGen should actually emit trivial
688 // dtors which shall be removed on later CIR passes. However, only remove this
689 // assertion after we have a test case to exercise this path.
690 assert(!dtor->isTrivial());
691 cgf.emitCXXDestructorCall(dtor, Dtor_Complete, /*forVirtualBase*/ false,
692 /*delegating=*/false, addr, type);
693}
694
696 const CXXConstructorDecl *ctor, const FunctionArgList &args) {
697 assert(ctor->isDelegatingConstructor());
698
699 Address thisPtr = loadCXXThisAddress();
700
707
708 emitAggExpr(ctor->init_begin()[0]->getInit(), aggSlot);
709
710 const CXXRecordDecl *classDecl = ctor->getParent();
711 if (cgm.getLangOpts().Exceptions && !classDecl->hasTrivialDestructor()) {
713 "emitDelegatingCXXConstructorCall: exception");
714 return;
715 }
716}
717
720 bool forVirtualBase, bool delegating,
721 Address thisAddr, QualType thisTy) {
722 cgm.getCXXABI().emitDestructorCall(*this, dd, type, forVirtualBase,
723 delegating, thisAddr, thisTy);
724}
725
727 Address value, const CXXRecordDecl *derived,
728 llvm::iterator_range<CastExpr::path_const_iterator> path,
729 bool nullCheckValue, SourceLocation loc) {
730 assert(!path.empty() && "Base path should not be empty!");
731
732 if ((*path.begin())->isVirtual()) {
733 // The implementation here is actually complete, but let's flag this
734 // as an error until the rest of the virtual base class support is in place.
735 cgm.errorNYI(loc, "getAddrOfBaseClass: virtual base");
736 return Address::invalid();
737 }
738
739 // Compute the static offset of the ultimate destination within its
740 // allocating subobject (the virtual base, if there is one, or else
741 // the "complete" object that we see).
742 CharUnits nonVirtualOffset =
744
745 // Get the base pointer type.
746 mlir::Type baseValueTy = convertType((path.end()[-1])->getType());
748
749 // The if statement here is redundant now, but it will be needed when we add
750 // support for virtual base classes.
751 // If there is no virtual base, use cir.base_class_addr. It takes care of
752 // the adjustment and the null pointer check.
753 if (nonVirtualOffset.isZero()) {
755 return builder.createBaseClassAddr(getLoc(loc), value, baseValueTy, 0,
756 /*assumeNotNull=*/true);
757 }
758
760
761 // Apply the offset
762 value = builder.createBaseClassAddr(getLoc(loc), value, baseValueTy,
763 nonVirtualOffset.getQuantity(),
764 /*assumeNotNull=*/true);
765
766 // Cast to the destination type.
767 value = value.withElementType(builder, baseValueTy);
768
769 return value;
770}
771
772// TODO(cir): this can be shared with LLVM codegen.
775 if (!cgm.getCodeGenOpts().WholeProgramVTables)
776 return false;
777
778 if (cgm.getCodeGenOpts().VirtualFunctionElimination)
779 return true;
780
782
783 return false;
784}
785
786mlir::Value CIRGenFunction::getVTablePtr(mlir::Location loc, Address thisAddr,
787 const CXXRecordDecl *rd) {
788 auto vtablePtr = cir::VTableGetVPtrOp::create(
789 builder, loc, builder.getPtrToVPtrType(), thisAddr.getPointer());
790 Address vtablePtrAddr = Address(vtablePtr, thisAddr.getAlignment());
791
792 auto vtable = builder.createLoad(loc, vtablePtrAddr);
794
795 if (cgm.getCodeGenOpts().OptimizationLevel > 0 &&
796 cgm.getCodeGenOpts().StrictVTablePointers) {
798 }
799
800 return vtable;
801}
802
805 bool forVirtualBase,
806 bool delegating,
807 AggValueSlot thisAVS,
808 const clang::CXXConstructExpr *e) {
809 CallArgList args;
810 Address thisAddr = thisAVS.getAddress();
811 QualType thisType = d->getThisType();
812 mlir::Value thisPtr = thisAddr.getPointer();
813
815
816 args.add(RValue::get(thisPtr), thisType);
817
818 // In LLVM Codegen: If this is a trivial constructor, just emit what's needed.
819 // If this is a union copy constructor, we must emit a memcpy, because the AST
820 // does not model that copy.
822
824
826
827 emitCallArgs(args, fpt, e->arguments(), e->getConstructor(),
828 /*ParamsToSkip=*/0);
829
831 emitCXXConstructorCall(d, type, forVirtualBase, delegating, thisAddr, args,
832 e->getExprLoc());
833}
834
836 const CXXConstructorDecl *d, CXXCtorType type, bool forVirtualBase,
837 bool delegating, Address thisAddr, CallArgList &args, SourceLocation loc) {
838
839 const CXXRecordDecl *crd = d->getParent();
840
841 // If this is a call to a trivial default constructor:
842 // In LLVM: do nothing.
843 // In CIR: emit as a regular call, other later passes should lower the
844 // ctor call into trivial initialization.
846
848
849 bool passPrototypeArgs = true;
850
851 // Check whether we can actually emit the constructor before trying to do so.
852 if (d->getInheritedConstructor()) {
854 "emitCXXConstructorCall: inherited constructor");
855 return;
856 }
857
858 // Insert any ABI-specific implicit constructor arguments.
860
861 // Emit the call.
862 auto calleePtr = cgm.getAddrOfCXXStructor(GlobalDecl(d, type));
864 args, d, type, passPrototypeArgs);
865 CIRGenCallee callee = CIRGenCallee::forDirect(calleePtr, GlobalDecl(d, type));
866 cir::CIRCallOpInterface c;
867 emitCall(info, callee, ReturnValueSlot(), args, &c, getLoc(loc));
868
869 if (cgm.getCodeGenOpts().OptimizationLevel != 0 && !crd->isDynamicClass() &&
870 type != Ctor_Base && cgm.getCodeGenOpts().StrictVTablePointers)
871 cgm.errorNYI(d->getSourceRange(), "vtable assumption loads");
872}
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)
Definition: CIRGenClass.cpp:74
static bool isInitializerOfDynamicClass(const CXXCtorInitializer *baseInit)
static void emitLValueForAnyFieldInitialization(CIRGenFunction &cgf, CXXCtorInitializer *memberInit, LValue &lhs)
Definition: CIRGenClass.cpp:58
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
cir::PointerType getPointerTo(mlir::Type ty)
mlir::Value createPtrBitcast(mlir::Value src, mlir::Type newPointeeTy)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
const ConstantArrayType * getAsConstantArrayType(QualType T) const
Definition: ASTContext.h:3056
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
CanQualType getCanonicalTagType(const TagDecl *TD) const
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
Definition: RecordLayout.h:38
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Definition: RecordLayout.h:250
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
Definition: RecordLayout.h:260
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
Definition: RecordLayout.h:235
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: TypeBase.h:3738
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
Definition: BaseSubobject.h:43
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
Definition: BaseSubobject.h:46
mlir::Value getPointer() const
Definition: Address.h:81
mlir::Type getElementType() const
Definition: Address.h:101
static Address invalid()
Definition: Address.h:66
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:109
An aggregate value slot.
Definition: CIRGenValue.h:302
static AggValueSlot forAddr(Address addr, clang::Qualifiers quals, IsDestructed_t isDestructed, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed)
Definition: CIRGenValue.h:359
Address getAddress() const
Definition: CIRGenValue.h:376
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)
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, mlir::IntegerAttr align={}, cir::MemOrderAttr order={})
virtual bool needsVTTParameter(clang::GlobalDecl gd)
Return whether the given global decl needs a VTT (virtual table table) parameter.
Definition: CIRGenCXXABI.h:72
virtual mlir::Value getVTableAddressPointInStructor(CIRGenFunction &cgf, const CXXRecordDecl *vtableClass, BaseSubobject base, const CXXRecordDecl *nearestVBase)=0
Get the address point of the vtable for the given base subobject while building a constructor or a de...
virtual void emitDestructorCall(CIRGenFunction &cgf, const CXXDestructorDecl *dd, CXXDtorType type, bool forVirtualBase, bool delegating, Address thisAddr, QualType thisTy)=0
virtual void initializeHiddenVirtualInheritanceMembers(CIRGenFunction &cgf, const CXXRecordDecl *rd)
Emit the code to initialize hidden members required to handle virtual inheritance,...
Definition: CIRGenCXXABI.h:43
virtual bool isVirtualOffsetNeededForVTableField(CIRGenFunction &cgf, CIRGenFunction::VPtr vptr)=0
Checks if ABI requires extra virtual offset for vtable field.
virtual bool doStructorsInitializeVPtrs(const clang::CXXRecordDecl *vtableClass)=0
Checks if ABI requires to initialize vptrs for given dynamic class.
static CIRGenCallee forDirect(mlir::Operation *funcPtr, const CIRGenCalleeInfo &abstractInfo=CIRGenCalleeInfo())
Definition: CIRGenCall.h:90
A scope within which we are constructing the fields of an object which might use a CXXDefaultInitExpr...
static bool isConstructorDelegationValid(const clang::CXXConstructorDecl *ctor)
Checks whether the given constructor is a valid subject for the complete-to-base constructor delegati...
Definition: CIRGenClass.cpp:29
void emitCallArgs(CallArgList &args, PrototypeWrapper prototype, llvm::iterator_range< clang::CallExpr::const_arg_iterator > argRange, AbstractCallee callee=AbstractCallee(), unsigned paramsToSkip=0)
Definition: CIRGenCall.cpp:731
mlir::Type convertType(clang::QualType t)
static cir::TypeEvaluationKind getEvaluationKind(clang::QualType type)
Return the cir::TypeEvaluationKind of QualType type.
clang::GlobalDecl curGD
The GlobalDecl for the current function being compiled or the global variable currently being initial...
const clang::LangOptions & getLangOpts() const
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...
clang::CharUnits cxxThisAlignment
const clang::Decl * curFuncDecl
LValue makeNaturalAlignAddrLValue(mlir::Value val, QualType ty)
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.
Definition: CIRGenDecl.cpp:487
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)
void emitImplicitAssignmentOperatorBody(FunctionArgList &args)
void emitCtorPrologue(const clang::CXXConstructorDecl *ctor, clang::CXXCtorType ctorType, FunctionArgList &args)
This routine generates necessary code to initialize base classes and non-static data members belongin...
static Destroyer destroyCXXObject
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.
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)
Definition: CIRGenCall.cpp:500
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...
Definition: CIRGenExpr.cpp:501
void emitInitializerForField(clang::FieldDecl *field, LValue lhs, clang::Expr *init)
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 emitCXXDestructorCall(const CXXDestructorDecl *dd, CXXDtorType type, bool forVirtualBase, bool delegating, Address thisAddr, QualType thisTy)
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.
Definition: CIRGenCall.cpp:257
std::optional< mlir::Location > currSrcLoc
Use to track source locations across nested visitor traversals.
clang::ASTContext & getContext() const
mlir::LogicalResult emitStmt(const clang::Stmt *s, bool useCurrentScope, llvm::ArrayRef< const Attr * > attrs={})
Definition: CIRGenStmt.cpp:110
void emitDelegatingCXXConstructorCall(const CXXConstructorDecl *ctor, const FunctionArgList &args)
void emitAggExpr(const clang::Expr *e, AggValueSlot slot)
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *derivedClass, llvm::iterator_range< CastExpr::path_const_iterator > path)
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
cir::FuncOp getAddrOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
Definition: CIRGenModule.h:240
clang::CharUnits getClassPointerAlignment(const clang::CXXRecordDecl *rd)
Return the best known alignment for an unknown pointer to a particular class.
const clang::TargetInfo & getTarget() const
Definition: CIRGenModule.h:103
const clang::CodeGenOptions & getCodeGenOpts() const
Definition: CIRGenModule.h:104
const clang::LangOptions & getLangOpts() const
Definition: CIRGenModule.h:107
CIRGenCXXABI & getCXXABI() const
Definition: CIRGenModule.h:109
const CIRGenFunctionInfo & arrangeCXXConstructorCall(const CallArgList &args, const clang::CXXConstructorDecl *d, clang::CXXCtorType ctorKind, bool passProtoArgs=true)
Arrange a call to a C++ method, passing the given arguments.
Definition: CIRGenCall.cpp:329
void add(RValue rvalue, clang::QualType type)
Definition: CIRGenCall.h:231
Type for representing both the decl and type of parameters to a function.
Definition: CIRGenCall.h:191
bool isSimple() const
Definition: CIRGenValue.h:190
static RValue get(mlir::Value v)
Definition: CIRGenValue.h:82
Contains the address where the return value of a function can be stored, and whether the address is v...
Definition: CIRGenCall.h:252
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1549
arg_range arguments()
Definition: ExprCXX.h:1673
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition: ExprCXX.h:1612
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2604
init_iterator init_begin()
Retrieve an iterator to the first initializer.
Definition: DeclCXX.h:2701
bool isDelegatingConstructor() const
Determine whether this constructor is a delegating constructor.
Definition: DeclCXX.h:2757
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
Definition: DeclCXX.cpp:3019
InheritedConstructor getInheritedConstructor() const
Get the constructor that this inheriting constructor is based on.
Definition: DeclCXX.h:2842
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2369
Expr * getInit() const
Get the initializer.
Definition: DeclCXX.h:2571
SourceRange getSourceRange() const LLVM_READONLY
Determine the source range covering the entire initializer.
Definition: DeclCXX.cpp:2916
bool isAnyMemberInitializer() const
Definition: DeclCXX.h:2449
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
Definition: DeclCXX.h:2441
bool isIndirectMemberInitializer() const
Definition: DeclCXX.h:2453
const Type * getBaseClass() const
If this is a base class initializer, returns the type of the base class.
Definition: DeclCXX.cpp:2896
FieldDecl * getAnyMember() const
Definition: DeclCXX.h:2515
IndirectFieldDecl * getIndirectMember() const
Definition: DeclCXX.h:2523
bool isBaseVirtual() const
Returns whether the base is virtual or not.
Definition: DeclCXX.h:2495
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2869
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition: DeclCXX.h:2255
QualType getThisType() const
Return the type of the this pointer.
Definition: DeclCXX.cpp:2809
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
Definition: DeclCXX.h:1366
base_class_range bases()
Definition: DeclCXX.h:608
bool isAbstract() const
Determine whether this class has a pure virtual function.
Definition: DeclCXX.h:1221
bool isDynamicClass() const
Definition: DeclCXX.h:574
CXXRecordDecl * getDefinitionOrSelf() const
Definition: DeclCXX.h:555
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
Definition: DeclCXX.h:623
Represents the this expression in C++.
Definition: ExprCXX.h:1155
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
bool isZero() const
isZero - Test whether the quantity equals zero.
Definition: CharUnits.h:122
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:185
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
Definition: CharUnits.h:214
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Definition: CharUnits.h:53
ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
Represents the canonical version of C arrays with a specified constant size.
Definition: TypeBase.h:3776
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Decl.h:830
This represents one expression.
Definition: Expr.h:112
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:273
Represents a member of a struct/union/class.
Definition: Decl.h:3157
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:4767
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition: Decl.h:2376
bool isDefaulted() const
Whether this function is defaulted.
Definition: Decl.h:2384
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:4490
Represents a prototype with parameter type info, e.g.
Definition: TypeBase.h:5282
bool isVariadic() const
Whether this function prototype is variadic.
Definition: TypeBase.h:5686
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:3464
ArrayRef< NamedDecl * > chain() const
Definition: Decl.h:3485
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:300
A (possibly-)qualified type.
Definition: TypeBase.h:937
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
Definition: TypeBase.h:1545
The collection of all-type qualifiers we support.
Definition: TypeBase.h:331
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: TypeBase.h:6502
RecordDecl * getOriginalDecl() const
Definition: TypeBase.h:6509
Encodes a location in the source.
Stmt - This represents one statement.
Definition: Stmt.h:85
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:334
bool hasConstructorVariants() const
Does this ABI have different entrypoints for complete-object and base-subobject constructors?
Definition: TargetCXXABI.h:194
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
Definition: TargetInfo.h:1360
The base class of the type hierarchy.
Definition: TypeBase.h:1833
CXXRecordDecl * castAsCXXRecordDecl() const
Definition: Type.h:36
const T * castAs() const
Member-template castAs<specific type>.
Definition: TypeBase.h:9226
bool isRecordType() const
Definition: TypeBase.h:8707
QualType getType() const
Definition: Decl.h:722
Represents a variable declaration or definition.
Definition: Decl.h:925
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
Matches all kinds of arrays.
The JSON file list parser is used to communicate input to InstallAPI.
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
CXXDtorType
C++ destructor types.
Definition: ABI.h:33
@ Dtor_Complete
Complete object dtor.
Definition: ABI.h:35
static bool implicitConstructorArgs()
static bool addressSpace()
static bool aggValueSlotGC()
static bool sanitizers()
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()
const clang::CXXRecordDecl * vtableClass
const clang::CXXRecordDecl * nearestVBase