Skip to content

Commit fcf3ca9

Browse files
committed
[clang][Interp][NFC] Split emitRecordDestruction
into a general part and a record part. This will be needed in future patches.
1 parent bb04909 commit fcf3ca9

File tree

2 files changed

+55
-44
lines changed

2 files changed

+55
-44
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 51 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3365,45 +3365,8 @@ bool ByteCodeExprGen<Emitter>::emitComplexReal(const Expr *SubExpr) {
33653365
return true;
33663366
}
33673367

3368-
/// When calling this, we have a pointer of the local-to-destroy
3369-
/// on the stack.
3370-
/// Emit destruction of record types (or arrays of record types).
33713368
template <class Emitter>
3372-
bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Descriptor *Desc) {
3373-
assert(Desc);
3374-
assert(!Desc->isPrimitive());
3375-
assert(!Desc->isPrimitiveArray());
3376-
3377-
// Arrays.
3378-
if (Desc->isArray()) {
3379-
const Descriptor *ElemDesc = Desc->ElemDesc;
3380-
assert(ElemDesc);
3381-
3382-
// Don't need to do anything for these.
3383-
if (ElemDesc->isPrimitiveArray())
3384-
return this->emitPopPtr(SourceInfo{});
3385-
3386-
// If this is an array of record types, check if we need
3387-
// to call the element destructors at all. If not, try
3388-
// to save the work.
3389-
if (const Record *ElemRecord = ElemDesc->ElemRecord) {
3390-
if (const CXXDestructorDecl *Dtor = ElemRecord->getDestructor();
3391-
!Dtor || Dtor->isTrivial())
3392-
return this->emitPopPtr(SourceInfo{});
3393-
}
3394-
3395-
for (ssize_t I = Desc->getNumElems() - 1; I >= 0; --I) {
3396-
if (!this->emitConstUint64(I, SourceInfo{}))
3397-
return false;
3398-
if (!this->emitArrayElemPtrUint64(SourceInfo{}))
3399-
return false;
3400-
if (!this->emitRecordDestruction(ElemDesc))
3401-
return false;
3402-
}
3403-
return this->emitPopPtr(SourceInfo{});
3404-
}
3405-
3406-
const Record *R = Desc->ElemRecord;
3369+
bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Record *R) {
34073370
assert(R);
34083371
// First, destroy all fields.
34093372
for (const Record::Field &Field : llvm::reverse(R->fields())) {
@@ -3413,7 +3376,9 @@ bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Descriptor *Desc) {
34133376
return false;
34143377
if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
34153378
return false;
3416-
if (!this->emitRecordDestruction(D))
3379+
if (!this->emitDestruction(D))
3380+
return false;
3381+
if (!this->emitPopPtr(SourceInfo{}))
34173382
return false;
34183383
}
34193384
}
@@ -3437,13 +3402,57 @@ bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Descriptor *Desc) {
34373402
for (const Record::Base &Base : llvm::reverse(R->bases())) {
34383403
if (!this->emitGetPtrBase(Base.Offset, SourceInfo{}))
34393404
return false;
3440-
if (!this->emitRecordDestruction(Base.Desc))
3405+
if (!this->emitRecordDestruction(Base.R))
3406+
return false;
3407+
if (!this->emitPopPtr(SourceInfo{}))
34413408
return false;
34423409
}
3410+
34433411
// FIXME: Virtual bases.
3412+
return true;
3413+
}
3414+
/// When calling this, we have a pointer of the local-to-destroy
3415+
/// on the stack.
3416+
/// Emit destruction of record types (or arrays of record types).
3417+
template <class Emitter>
3418+
bool ByteCodeExprGen<Emitter>::emitDestruction(const Descriptor *Desc) {
3419+
assert(Desc);
3420+
assert(!Desc->isPrimitive());
3421+
assert(!Desc->isPrimitiveArray());
3422+
3423+
// Arrays.
3424+
if (Desc->isArray()) {
3425+
const Descriptor *ElemDesc = Desc->ElemDesc;
3426+
assert(ElemDesc);
3427+
3428+
// Don't need to do anything for these.
3429+
if (ElemDesc->isPrimitiveArray())
3430+
return true;
3431+
3432+
// If this is an array of record types, check if we need
3433+
// to call the element destructors at all. If not, try
3434+
// to save the work.
3435+
if (const Record *ElemRecord = ElemDesc->ElemRecord) {
3436+
if (const CXXDestructorDecl *Dtor = ElemRecord->getDestructor();
3437+
!Dtor || Dtor->isTrivial())
3438+
return true;
3439+
}
3440+
3441+
for (ssize_t I = Desc->getNumElems() - 1; I >= 0; --I) {
3442+
if (!this->emitConstUint64(I, SourceInfo{}))
3443+
return false;
3444+
if (!this->emitArrayElemPtrUint64(SourceInfo{}))
3445+
return false;
3446+
if (!this->emitDestruction(ElemDesc))
3447+
return false;
3448+
if (!this->emitPopPtr(SourceInfo{}))
3449+
return false;
3450+
}
3451+
return true;
3452+
}
34443453

3445-
// Remove the instance pointer.
3446-
return this->emitPopPtr(SourceInfo{});
3454+
assert(Desc->ElemRecord);
3455+
return this->emitRecordDestruction(Desc->ElemRecord);
34473456
}
34483457

34493458
namespace clang {

clang/lib/AST/Interp/ByteCodeExprGen.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,8 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
289289

290290
bool emitComplexReal(const Expr *SubExpr);
291291

292-
bool emitRecordDestruction(const Descriptor *Desc);
292+
bool emitRecordDestruction(const Record *R);
293+
bool emitDestruction(const Descriptor *Desc);
293294
unsigned collectBaseOffset(const RecordType *BaseType,
294295
const RecordType *DerivedType);
295296

@@ -401,7 +402,8 @@ template <class Emitter> class LocalScope : public VariableScope<Emitter> {
401402
for (Scope::Local &Local : this->Ctx->Descriptors[*Idx]) {
402403
if (!Local.Desc->isPrimitive() && !Local.Desc->isPrimitiveArray()) {
403404
this->Ctx->emitGetPtrLocal(Local.Offset, SourceInfo{});
404-
this->Ctx->emitRecordDestruction(Local.Desc);
405+
this->Ctx->emitDestruction(Local.Desc);
406+
this->Ctx->emitPopPtr(SourceInfo{});
405407
removeIfStoredOpaqueValue(Local);
406408
}
407409
}

0 commit comments

Comments
 (0)