85 for (
const auto *nd : indirectField->
chain()) {
100 "Must have member initializer!");
101 assert(memberInit->
getInit() &&
"Must have initializer!");
133 unsigned srcArgIndex =
145 lhs.isVolatileQualified());
149 "Arrays of non-record types shouldn't need EH cleanup");
160 const CXXRecordDecl *baseClass;
162 CallBaseDtor(
const CXXRecordDecl *base,
bool baseIsVirtual)
163 : baseClass(base), baseIsVirtual(baseIsVirtual) {}
165 void emit(CIRGenFunction &cgf, Flags flags)
override {
166 const CXXRecordDecl *derivedClass =
169 const CXXDestructorDecl *d = baseClass->getDestructor();
173 assert(cgf.
currSrcLoc &&
"expected source location");
176 baseClass, baseIsVirtual);
178 false, addr, thisTy);
186 const CXXDestructorDecl *dtor;
190 CallDelegatingCtorDtor(
const CXXDestructorDecl *dtor, Address addr,
192 : dtor(dtor), addr(addr),
type(
type) {}
194 void emit(CIRGenFunction &cgf, Flags flags)
override {
195 QualType thisTy = dtor->getFunctionObjectParameterType();
222 return builder.createBaseClassAddr(loc, thisAddr,
convertType(base),
230 assert(
curFuncDecl &&
"loading 'this' without a func declaration?");
251 loc, thisPtr, classDecl, baseClassDecl, isBaseVirtual);
259 if (
cgm.getLangOpts().Exceptions && !baseClassDecl->hasTrivialDestructor())
283 bool constructVBases = ctorType !=
Ctor_Base &&
286 if (constructVBases &&
287 !
cgm.getTarget().getCXXABI().hasConstructorVariants()) {
289 "emitCtorPrologue: virtual base without variants");
294 auto allInits = cd->
inits();
297 auto virtualBaseEnd = std::find_if(
299 return !(Init->isBaseInitializer() && Init->isBaseVirtual());
302 auto nonVirtualBaseEnd = std::find_if(virtualBaseEnd, allInits.end(),
304 return !Init->isBaseInitializer();
308 auto virtualBaseInits = llvm::make_range(allInits.begin(), virtualBaseEnd);
309 auto nonVirtualBaseInits =
310 llvm::make_range(virtualBaseEnd, nonVirtualBaseEnd);
311 auto memberInits = llvm::make_range(nonVirtualBaseEnd, allInits.end());
316 if (
cgm.getCodeGenOpts().StrictVTablePointers &&
317 cgm.getCodeGenOpts().OptimizationLevel > 0 &&
322 "emitCtorPrologue: strict vtable pointers for vbase");
329 if (!constructVBases)
331 emitInitializer(virtualBaseInit);
338 assert(!nonVirtualBaseInit->isBaseVirtual());
339 emitInitializer(nonVirtualBaseInit);
354 assert(!member->isBaseInitializer());
355 assert(member->isAnyMemberInitializer() &&
356 "Delegating initializer on non-delegating constructor");
363 CharUnits nonVirtualOffset, mlir::Value virtualOffset,
365 mlir::Type baseValueTy = {},
bool assumeNotNull =
true) {
367 assert(!nonVirtualOffset.
isZero() || virtualOffset !=
nullptr);
370 mlir::Value baseOffset;
371 if (!nonVirtualOffset.
isZero()) {
373 mlir::Type offsetType =
382 assert(baseValueTy &&
"expected base type");
385 loc, addr, baseValueTy, nonVirtualOffset.
getQuantity(),
389 baseOffset = virtualOffset;
396 mlir::Type charPtrType =
399 mlir::Value adjusted = cir::PtrStrideOp::create(
400 cgf.
getBuilder(), loc, charPtrType, charPtr, baseOffset);
407 assert(nearestVBase &&
"virtual offset without vbase?");
415 return Address(ptr, alignment);
421 mlir::Value vtableAddressPoint =
422 cgm.getCXXABI().getVTableAddressPointInStructor(
425 if (!vtableAddressPoint)
429 mlir::Value virtualOffset{};
432 mlir::Type baseValueTy;
433 if (
cgm.getCXXABI().isVirtualOffsetNeededForVTableField(*
this, vptr)) {
436 virtualOffset =
cgm.getCXXABI().getVirtualBaseClassOffset(
448 if (!nonVirtualOffset.
isZero() || virtualOffset) {
450 loc, *
this, classAddr, nonVirtualOffset, virtualOffset,
460 cir::VTableGetVPtrOp::create(builder, loc, classAddr.
getPointer());
462 builder.createStore(loc, vtableAddressPoint, vtableField);
474 if (
cgm.getCXXABI().doStructorsInitializeVPtrs(rd))
479 cgm.getCXXABI().initializeHiddenVirtualInheritanceMembers(*
this, rd);
489 false, vtableClass, vbases,
497 bool baseIsNonVirtualPrimaryBase,
503 if (!baseIsNonVirtualPrimaryBase) {
505 VPtr vptr = {base, nearestVBase, offsetFromNearestVBase, vtableClass};
506 vptrs.push_back(vptr);
511 for (
const auto &nextBase : rd->
bases()) {
512 const auto *baseDecl =
514 ->getDefinitionOrSelf();
517 if (!baseDecl->isDynamicClass())
522 bool baseDeclIsNonVirtualPrimaryBase;
525 if (nextBase.isVirtual()) {
527 if (!vbases.insert(baseDecl).second)
533 nextBaseDecl = baseDecl;
536 baseDeclIsNonVirtualPrimaryBase =
false;
540 nextBaseDecl = nearestVBase;
542 baseOffsetFromNearestVBase =
544 baseDeclIsNonVirtualPrimaryBase = layout.
getPrimaryBase() == baseDecl;
548 baseOffsetFromNearestVBase,
549 baseDeclIsNonVirtualPrimaryBase, vtableClass, vbases,
555 assert(
curFuncDecl &&
"loading 'this' without a func declaration?");
603 const Expr *e,
Address base, mlir::Value memberPtr,
607 cir::GetRuntimeMemberOp op = builder.createGetIndirectMember(
612 CharUnits memberAlign =
cgm.getNaturalTypeAlignment(memberType, baseInfo);
613 memberAlign =
cgm.getDynamicOffsetAlignment(
628 return std::min(actualBaseAlign, expectedTargetAlign);
652 if (actualBaseAlign >= expectedBaseAlign)
653 return expectedTargetAlign;
658 return std::min(actualBaseAlign, expectedTargetAlign);
690 bool zeroInitialize) {
694 newPointerIsChecked, zeroInitialize,
726 while (
auto maybeArrayTy = mlir::dyn_cast<cir::ArrayType>(elementType))
727 elementType = maybeArrayTy.getElementType();
728 cir::PointerType ptrToElmType = builder.getPointerTo(elementType);
730 bool useDynamicArrayCtor =
true;
731 uint64_t constElementCount = 0;
732 if (
auto constantOp = numElements.getDefiningOp<cir::ConstantOp>()) {
734 if (constElementCount == 0)
736 if (constantOp.use_empty())
738 useDynamicArrayCtor =
false;
756 mlir::Value dynamicElPtr;
757 if (useDynamicArrayCtor)
759 builder.createPtrBitcast(arrayBase.
getPointer(), elementType);
765 bool needsPartialArrayCleanup =
getLangOpts().Exceptions &&
769 auto emitCtorBody = [&](mlir::OpBuilder &b, mlir::Location l) {
770 mlir::BlockArgument arg =
771 b.getInsertionBlock()->addArgument(ptrToElmType, l);
777 builder.createStore(l, arg, endOfInit);
798 cir::YieldOp::create(b, l);
801 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)>
802 emitPartialDtorBody =
nullptr;
803 auto partialDtorBuilder = [&](mlir::OpBuilder &b, mlir::Location l) {
804 mlir::BlockArgument arg =
805 b.getInsertionBlock()->addArgument(ptrToElmType, l);
809 false, curAddr,
type);
810 cir::YieldOp::create(b, l);
812 if (needsPartialArrayCleanup)
813 emitPartialDtorBody = partialDtorBuilder;
815 if (useDynamicArrayCtor) {
816 cir::ArrayCtor::create(builder, loc, dynamicElPtr, numElements,
817 emitCtorBody, emitPartialDtorBody);
819 cir::ArrayType arrayTy =
820 cir::ArrayType::get(elementType, constElementCount);
821 mlir::Value arrayOp =
822 builder.createPtrBitcast(arrayBase.
getPointer(), arrayTy);
823 cir::ArrayCtor::create(builder, loc, arrayOp, emitCtorBody,
824 emitPartialDtorBody);
833 FunctionArgList::const_iterator i = args.begin(), e = args.end();
834 assert(i != e &&
"no parameters to constructor");
843 if (
cgm.getCXXABI().needsVTTParameter(
curGD)) {
844 cgm.errorNYI(loc,
"emitDelegateCXXConstructorCall: VTT parameter");
849 for (; i != e; ++i) {
858 true, thisAddr, delegateArgs, loc);
863 assert(assignOp->isCopyAssignmentOperator() ||
864 assignOp->isMoveAssignmentOperator());
865 const Stmt *rootS = assignOp->getBody();
867 "Body of an implicit assignment operator should be compound stmt.");
881 for (
Stmt *s : rootCS->body())
883 cgm.errorNYI(s->getSourceRange(),
884 std::string(
"emitImplicitAssignmentOperatorBody: ") +
885 s->getStmtClassName());
892 cgm.getTypes().arrangeCXXMethodDeclaration(callOperator);
893 cir::FuncOp calleePtr =
cgm.getAddrOfFunction(
894 GlobalDecl(callOperator),
cgm.getTypes().getFunctionType(calleeFnInfo));
922 if (!resultType->isVoidType()) {
924 resultType->isObjCRetainableType())
926 "emitForwardingCallToLambda: ObjCAutoRefCount");
957 llvm::FoldingSetInsertToken InsertToken;
960 assert(correspondingCallOpSpecialization);
980 const auto *record =
type->castAsCXXRecordDecl();
1011 const FieldDecl *field;
1016 : field(field), destroyer(destroyer) {}
1018 void emit(CIRGenFunction &cgf, Flags flags)
override {
1025 assert(lv.isSimple());
1028 cgf.
emitDestroy(lv.getAddress(), field->getType(), destroyer);
1042 "Should not emit dtor epilogue for non-exported trivial dtor!");
1048 "operator delete missing - EnterDtorCleanups");
1052 assert(
getTarget().getCXXABI().isMicrosoft() &&
1053 "only the Microsoft ABI passes an implicit deleting dtor param");
1055 "deleting destructor with conditional delete: MSVC ABI");
1059 "destroying operator delete is handled by emitDestructorBody");
1078 auto *baseClassDecl = base.getType()->castAsCXXRecordDecl();
1080 if (baseClassDecl->hasTrivialDestructor()) {
1100 if (base.isVirtual())
1103 CXXRecordDecl *baseClassDecl = base.getType()->getAsCXXRecordDecl();
1122 const RecordType *rt =
type->getAsUnionType();
1123 if (rt && rt->getDecl()->isAnonymousStructOrUnion())
1128 ehStack.pushCleanup<DestroyField>(cleanupKind, field,
1152 ehStack.pushCleanup<CallDelegatingCtorDtor>(
1159 bool forVirtualBase,
bool delegating,
1161 cgm.getCXXABI().emitDestructorCall(*
this, dd,
type, forVirtualBase,
1162 delegating, thisAddr, thisTy);
1167 if (!
cgm.getCXXABI().needsVTTParameter(gd))
1173 uint64_t subVTTIndex;
1178 }
else if (rd == base) {
1181 assert(!
cgm.getCXXABI().needsVTTParameter(
curGD) &&
1182 "doing no-op VTT offset in base dtor/ctor?");
1183 assert(!forVirtualBase &&
"Can't have same class as virtual base!");
1192 assert(subVTTIndex != 0 &&
"Sub-VTT index must be greater than zero!");
1196 if (
cgm.getCXXABI().needsVTTParameter(
curGD)) {
1199 return builder.createVTTAddrPoint(loc, vtt.getType(), vtt, subVTTIndex);
1202 cir::GlobalOp vtt =
cgm.getVTables().getAddrOfVTT(rd);
1203 return builder.createVTTAddrPoint(
1204 loc, builder.getPointerTo(
cgm.voidPtrTy),
1205 mlir::FlatSymbolRefAttr::get(vtt.getSymNameAttr()), subVTTIndex);
1211 llvm::iterator_range<CastExpr::path_const_iterator> path,
1212 bool nullCheckValue) {
1213 assert(!path.empty() &&
"Base path should not be empty!");
1216 mlir::Type derivedValueTy =
convertType(derivedTy);
1218 cgm.computeNonVirtualBaseClassOffset(derived, path);
1223 return builder.createDerivedClassAddr(loc, baseAddr, derivedValueTy,
1230 llvm::iterator_range<CastExpr::path_const_iterator> path,
1232 assert(!path.empty() &&
"Base path should not be empty!");
1237 if ((*path.begin())->isVirtual()) {
1238 vBase = (*start)->getType()->castAsCXXRecordDecl();
1245 CharUnits nonVirtualOffset =
cgm.computeNonVirtualBaseClassOffset(
1246 vBase ? vBase : derived, {start, path.end()});
1251 if (vBase && derived->
hasAttr<FinalAttr>()) {
1254 nonVirtualOffset += vBaseOffset;
1259 mlir::Type baseValueTy =
convertType((path.end()[-1])->getType());
1263 if (nonVirtualOffset.
isZero() && !vBase) {
1265 return builder.createBaseClassAddr(
getLoc(loc), value, baseValueTy, 0,
1271 mlir::Location mlirLoc =
getLoc(loc);
1276 if (vBase && nullCheckValue) {
1279 .alignmentAtOffset(nonVirtualOffset);
1280 mlir::Type basePtrTy =
1282 mlir::Value ptrIsNull = builder.createPtrIsNull(value.
getPointer());
1283 mlir::Value result =
1284 cir::TernaryOp::create(
1285 builder, mlirLoc, ptrIsNull,
1286 [&](mlir::OpBuilder &, mlir::Location) {
1287 builder.createYield(
1288 mlirLoc, builder.getNullPtr(basePtrTy, mlirLoc).getResult());
1290 [&](mlir::OpBuilder &, mlir::Location) {
1291 mlir::Value virtualOffset =
1292 cgm.getCXXABI().getVirtualBaseClassOffset(
1293 mlirLoc, *
this, value, derived, vBase);
1295 mlirLoc, *
this, value, nonVirtualOffset, virtualOffset,
1296 derived, vBase, baseValueTy,
true);
1298 builder.createYield(mlirLoc, adjusted.
getPointer());
1301 return Address(result, baseValueTy, alignment);
1305 mlir::Value virtualOffset =
nullptr;
1307 virtualOffset =
cgm.getCXXABI().getVirtualBaseClassOffset(
1308 mlirLoc, *
this, value, derived, vBase);
1313 mlirLoc, *
this, value, nonVirtualOffset, virtualOffset, derived, vBase,
1314 baseValueTy,
not nullCheckValue);
1325 if (!
cgm.getCodeGenOpts().WholeProgramVTables)
1328 if (
cgm.getCodeGenOpts().VirtualFunctionElimination)
1339 cir::VTableGetVPtrOp::create(builder, loc, thisAddr.
getPointer());
1342 auto vtable = builder.createLoad(loc, vtablePtrAddr);
1345 if (
cgm.getCodeGenOpts().OptimizationLevel > 0 &&
1346 cgm.getCodeGenOpts().StrictVTablePointers) {
1355 bool forVirtualBase,
1369 assert(e->
getNumArgs() == 1 &&
"unexpected argcount for trivial ctor");
1386 !inherited ||
cgm.getTypes().inheritingCtorHasParams(inherited,
type))
1411 "canEmitDelegateCallArgs: args-destroyed-L-to-R in callee");
1426 if (inheritedFromVBase &&
1427 cgm.getTarget().getCXXABI().hasConstructorVariants()) {
1430 ctorArgs.push_back(thisArg);
1434 "wrong number of parameters for inherited constructor call");
1436 ctorArgs[0] = thisArg;
1438 ctorArgs.push_back(thisArg);
1440 assert(outerCtor->getNumParams() == d->
getNumParams());
1441 assert(!outerCtor->isVariadic() &&
"should have been inlined");
1443 for (
const ParmVarDecl *param : outerCtor->parameters()) {
1445 outerCtor->getParamDecl(param->getFunctionScopeIndex())->getType(),
1449 if (param->hasAttr<PassObjectSizeAttr>())
1452 "emitInheritedCXXConstructorCall: pass object size attr argument");
1462 bool forVirtualBase,
bool delegating,
CallArgList &args) {
1465 InlinedInheritingConstructorScope scope(*
this, gd);
1478 cgm.getCXXABI().addImplicitConstructorArgs(*
this, d, ctorType, forVirtualBase,
1482 assert(args.size() >= params.size() &&
"too few arguments for call");
1483 for (
auto [idx, arg, parm] :
1484 llvm::zip_longest(llvm::index_range{0, args.size()}, args, params)) {
1486 mlir::Location parmLoc =
getLoc((*parm)->getSourceRange());
1487 RValue argVal = arg->getRValue(*
this, parmLoc);
1492 (*parm)->getType());
1504 "emitInlinedInheritingCXXConstructorCall: non-void return");
1506 cgm.getCXXABI().emitInstanceFunctionProlog(loc, *
this);
1526 bool passPrototypeArgs =
true;
1531 if (passPrototypeArgs &&
1541 cgm.getCXXABI().addImplicitConstructorArgs(*
this, d,
type, forVirtualBase,
1549 cir::CIRCallOpInterface c;
static bool emit(llvm::SmallVectorImpl< std::byte > &Code, const T &Val)
Helper to write bytecode and bail out if 32-bit offsets become invalid.
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 canEmitDelegateCallArgs(CIRGenModule &cgm, ASTContext &ctx, const CXXConstructorDecl *d, CXXCtorType type)
static void emitLValueForAnyFieldInitialization(CIRGenFunction &cgf, CXXCtorInitializer *memberInit, LValue &lhs)
Defines the clang::Expr interface and subclasses for C++ expressions.
C Language Family Type Representation.
mlir::Value createAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, OverflowBehavior ob=OverflowBehavior::None)
cir::PointerType getPointerTo(mlir::Type ty)
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 ...
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.
const TargetInfo & getTargetInfo() const
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.
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
mlir::ptr::MemorySpaceAttrInterface getAddressSpace() const
mlir::Value getPointer() const
mlir::Type getElementType() const
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
Overlap_t mayOverlap() const
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 getAddress() const
cir::LoadOp createLoad(mlir::Location loc, Address addr, bool isVolatile=false, bool isNontemporal=false)
Address createBaseClassAddr(mlir::Location loc, Address addr, mlir::Type destType, unsigned offset, bool assumeNotNull)
cir::ConstantOp getConstInt(mlir::Location loc, llvm::APSInt intVal)
virtual size_t getSrcArgforCopyCtor(const CXXConstructorDecl *, FunctionArgList &args) const =0
static CIRGenCallee forDirect(mlir::Operation *funcPtr, const CIRGenCalleeInfo &abstractInfo=CIRGenCalleeInfo())
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)
CIRGenTypes & getTypes() const
const clang::LangOptions & getLangOpts() const
mlir::Value cxxStructorImplicitParamValue
cir::AllocaOp createTempAlloca(mlir::Type ty, mlir::Location loc, const Twine &name="tmp", mlir::Value arraySize=nullptr, bool insertIntoFnEntryBlock=false)
This creates an alloca and inserts it into the entry block if ArraySize is nullptr,...
void emitForwardingCallToLambda(const CXXMethodDecl *lambdaCallOperator, CallArgList &callArgs)
mlir::Value loadCXXThis()
Load the value for 'this'.
LValue makeNaturalAlignPointeeAddrLValue(mlir::Value v, clang::QualType t)
Given a value of type T* that may not be to a complete object, construct an l-vlaue withi the natural...
void emitDeleteCall(const FunctionDecl *deleteFD, mlir::Value ptr, QualType deleteTy)
clang::CharUnits cxxThisAlignment
const TargetInfo & getTarget() const
LValue emitLValue(const clang::Expr *e)
Emit code to compute a designator that specifies the location of the expression.
const clang::Decl * curFuncDecl
Address loadCXXThisAddress()
void emitInlinedInheritingCXXConstructorCall(SourceLocation loc, const CXXConstructorDecl *d, CXXCtorType ctorType, bool forVirtualBase, bool delegating, CallArgList &args)
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)
CallArgList cxxInheritedCtorInitExprArgs
The values of function arguments to use when evaluating CXXInheritedCtorInitExprs within this context...
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)
static int64_t getZExtIntValueFromConstOp(mlir::Value val)
Get zero-extended integer from a mlir::Value that is an int constant or a constant op.
mlir::Type convertTypeForMem(QualType t)
clang::QualType buildFunctionArgList(clang::GlobalDecl gd, FunctionArgList &args)
void emitCtorPrologue(const clang::CXXConstructorDecl *ctor, clang::CXXCtorType ctorType, FunctionArgList &args)
This routine generates necessary code to initialize base classes and non-static data members belongin...
mlir::Value loadCXXVTT()
Load the VTT parameter to base constructors/destructors have virtual bases.
static Destroyer destroyCXXObject
Address returnValue
The temporary alloca to hold the return value.
void emitCXXConstructorCall(const clang::CXXConstructorDecl *d, clang::CXXCtorType type, bool forVirtualBase, bool delegating, AggValueSlot thisAVS, const clang::CXXConstructExpr *e)
static bool hasAggregateEvaluationKind(clang::QualType type)
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...
const clang::Decl * curCodeDecl
This is the inner-most code context, which includes blocks.
LValue emitLValueForFieldInitialization(LValue base, const clang::FieldDecl *field, llvm::StringRef fieldName)
Like emitLValueForField, excpet that if the Field is a reference, this will return the address of the...
mlir::Value getAsNaturalPointerTo(Address addr, QualType pointeeType)
void emitInitializerForField(clang::FieldDecl *field, LValue lhs, clang::Expr *init)
mlir::Value loadThisForDtorDelete(const CXXDestructorDecl *dd)
Return the pointer to pass to the operator delete of the given destructor, converted to the type of i...
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)
std::optional< SourceRange > currSrcLoc
Use to track source locations across nested visitor traversals.
void emitComplexExprIntoLValue(const Expr *e, LValue dest, bool isInit)
void pushEHDestroyIfNeeded(QualType::DestructionKind dtorKind, Address addr, QualType type)
pushEHDestroyIfNeeded - Push the standard destructor for the given type as an EH-only cleanup.
RValue emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, const CallArgList &args, cir::CIRCallOpInterface *callOp, bool isMustTail, SourceRange clangLoc)
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.
clang::ASTContext & getContext() const
void setAddrOfLocalVar(const clang::VarDecl *vd, Address addr)
Set the address of a local variable.
void emitInheritedCXXConstructorCall(const CXXConstructorDecl *d, bool forVirtualBase, Address thisAddr, bool inheritedFromVBase, const CXXInheritedCtorInitExpr *e)
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::Value cxxabiThisValue
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)
This class organizes the cross-function state that is used while generating CIR code.
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.
const clang::TargetInfo & getTarget() const
const clang::LangOptions & getLangOpts() const
CIRGenCXXABI & getCXXABI() const
bool inheritingCtorHasParams(const InheritedConstructor &inherited, CXXCtorType type)
Determine if a C++ inheriting constructor should have parameters matching those of its inherited cons...
void add(RValue rvalue, clang::QualType type)
Information for lazily generating a cleanup.
Type for representing both the decl and type of parameters to a function.
Address getAddress() const
clang::QualType getType() const
This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(mlir::Value v)
Contains the address where the return value of a function can be stored, and whether the address is v...
Represents a base class of a C++ class.
Represents a call to a C++ constructor.
Expr * getArg(unsigned Arg)
Return the specified argument.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ constructor within a class.
init_iterator init_begin()
Retrieve an iterator to the first initializer.
bool isDelegatingConstructor() const
Determine whether this constructor is a delegating constructor.
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
InheritedConstructor getInheritedConstructor() const
Get the constructor that this inheriting constructor is based on.
Represents a C++ base or member initializer.
Expr * getInit() const
Get the initializer.
SourceLocation getSourceLocation() const
Determine the source location of the initializer.
bool isAnyMemberInitializer() const
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
bool isIndirectMemberInitializer() const
const Type * getBaseClass() const
If this is a base class initializer, returns the type of the base class.
FieldDecl * getAnyMember() const
IndirectFieldDecl * getIndirectMember() const
bool isBaseVirtual() const
Returns whether the base is virtual or not.
Represents a C++ destructor within a class.
const FunctionDecl * getOperatorDelete() const
Expr * getOperatorDeleteThisArg() const
Represents a call to an inherited base class constructor from an inheriting constructor.
SourceLocation getLocation() const LLVM_READONLY
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getThisType() const
Return the type of the this pointer.
QualType getFunctionObjectParameterType() const
bool isMemcpyEquivalentSpecialMember(const ASTContext &Ctx) const
Returns whether this is a copy/move constructor or assignment operator that can be implemented as a m...
Represents a C++ struct/union/class.
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
base_class_range vbases()
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool isDynamicClass() const
bool hasDefinition() const
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
const CXXBaseSpecifier *const * path_const_iterator
This is an opaque type for sizes expressed in character units.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isZero() const
Test whether the quantity equals zero.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits One()
Construct a CharUnits quantity of one.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
static CharUnits Zero()
Construct a CharUnits quantity of zero.
Represents the canonical version of C arrays with a specified constant size.
SourceLocation getBeginLoc() const LLVM_READONLY
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
Represents a function declaration or definition.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
bool isDestroyingOperatorDelete() const
Determine whether this is a destroying operator delete.
ArrayRef< ParmVarDecl * > parameters() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
bool isVariadic() const
Whether this function is variadic.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isDefaulted() const
Whether this function is defaulted.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Represents a prototype with parameter type info, e.g.
bool isVariadic() const
Whether this function prototype is variadic.
Declaration of a template function.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
QualType getReturnType() const
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
const Decl * getDecl() const
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Represents a parameter to a function.
A (possibly-)qualified type.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
The collection of all-type qualifiers we support.
field_range fields() const
Encodes a location in the source.
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
bool areArgsDestroyedLeftToRightInCallee() const
Are arguments to a call destroyed left to right in the callee?
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
A template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
SourceLocation getBeginLoc() const LLVM_READONLY
CXXRecordDecl * castAsCXXRecordDecl() const
const T * castAs() const
Member-template castAs<specific type>.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isRecordType() const
Represents a variable declaration or definition.
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
bool isInitializerOfDynamicClass(const CXXCtorInitializer *BaseInit)
Return whether BaseInit initializes a base class that is dynamic, that is, one whose vtable pointer m...
bool baseInitializerUsesThis(ASTContext &Ctx, const Expr *Init)
Check whether Init uses 'this' in a way which requires the vtable to be properly set.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
@ Address
A pointer to a ValueDecl.
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
CXXDtorType
C++ destructor types.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
U cast(CodeGen::Address addr)
static bool addressSpace()
static bool useEHCleanupForArray()
static bool aggValueSlotGC()
static bool hiddenVisibility()
static bool runCleanupsScope()
static bool opCallArgEvaluationOrder()
static bool createInvariantGroup()
static bool isTrivialCtorOrDtor()
static bool returnValueSlotFeatures()
static bool assignMemcpyizer()
static bool ctorMemcpyizer()
static bool generateDebugInfo()
static bool incrementProfileCounter()
Similar to AddedStructorArgs, but only notes the number of additional arguments.
const clang::CXXRecordDecl * vtableClass
clang::CharUnits offsetFromNearestVBase
const clang::CXXRecordDecl * nearestVBase
clang::BaseSubobject base