[clang] fcf3ca9 - [clang][Interp][NFC] Split emitRecordDestruction
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 19 00:23:49 PST 2024
Author: Timm Bäder
Date: 2024-02-19T09:23:31+01:00
New Revision: fcf3ca9a5e50f32edcfe68c291edd1ecab7009a7
URL: https://github.com/llvm/llvm-project/commit/fcf3ca9a5e50f32edcfe68c291edd1ecab7009a7
DIFF: https://github.com/llvm/llvm-project/commit/fcf3ca9a5e50f32edcfe68c291edd1ecab7009a7.diff
LOG: [clang][Interp][NFC] Split emitRecordDestruction
into a general part and a record part. This will be needed in future
patches.
Added:
Modified:
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/ByteCodeExprGen.h
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 6ad75d4e034a9d..e8b0fffd5ee34d 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -3365,45 +3365,8 @@ bool ByteCodeExprGen<Emitter>::emitComplexReal(const Expr *SubExpr) {
return true;
}
-/// When calling this, we have a pointer of the local-to-destroy
-/// on the stack.
-/// Emit destruction of record types (or arrays of record types).
template <class Emitter>
-bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Descriptor *Desc) {
- assert(Desc);
- assert(!Desc->isPrimitive());
- assert(!Desc->isPrimitiveArray());
-
- // Arrays.
- if (Desc->isArray()) {
- const Descriptor *ElemDesc = Desc->ElemDesc;
- assert(ElemDesc);
-
- // Don't need to do anything for these.
- if (ElemDesc->isPrimitiveArray())
- return this->emitPopPtr(SourceInfo{});
-
- // If this is an array of record types, check if we need
- // to call the element destructors at all. If not, try
- // to save the work.
- if (const Record *ElemRecord = ElemDesc->ElemRecord) {
- if (const CXXDestructorDecl *Dtor = ElemRecord->getDestructor();
- !Dtor || Dtor->isTrivial())
- return this->emitPopPtr(SourceInfo{});
- }
-
- for (ssize_t I = Desc->getNumElems() - 1; I >= 0; --I) {
- if (!this->emitConstUint64(I, SourceInfo{}))
- return false;
- if (!this->emitArrayElemPtrUint64(SourceInfo{}))
- return false;
- if (!this->emitRecordDestruction(ElemDesc))
- return false;
- }
- return this->emitPopPtr(SourceInfo{});
- }
-
- const Record *R = Desc->ElemRecord;
+bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Record *R) {
assert(R);
// First, destroy all fields.
for (const Record::Field &Field : llvm::reverse(R->fields())) {
@@ -3413,7 +3376,9 @@ bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Descriptor *Desc) {
return false;
if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
return false;
- if (!this->emitRecordDestruction(D))
+ if (!this->emitDestruction(D))
+ return false;
+ if (!this->emitPopPtr(SourceInfo{}))
return false;
}
}
@@ -3437,13 +3402,57 @@ bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Descriptor *Desc) {
for (const Record::Base &Base : llvm::reverse(R->bases())) {
if (!this->emitGetPtrBase(Base.Offset, SourceInfo{}))
return false;
- if (!this->emitRecordDestruction(Base.Desc))
+ if (!this->emitRecordDestruction(Base.R))
+ return false;
+ if (!this->emitPopPtr(SourceInfo{}))
return false;
}
+
// FIXME: Virtual bases.
+ return true;
+}
+/// When calling this, we have a pointer of the local-to-destroy
+/// on the stack.
+/// Emit destruction of record types (or arrays of record types).
+template <class Emitter>
+bool ByteCodeExprGen<Emitter>::emitDestruction(const Descriptor *Desc) {
+ assert(Desc);
+ assert(!Desc->isPrimitive());
+ assert(!Desc->isPrimitiveArray());
+
+ // Arrays.
+ if (Desc->isArray()) {
+ const Descriptor *ElemDesc = Desc->ElemDesc;
+ assert(ElemDesc);
+
+ // Don't need to do anything for these.
+ if (ElemDesc->isPrimitiveArray())
+ return true;
+
+ // If this is an array of record types, check if we need
+ // to call the element destructors at all. If not, try
+ // to save the work.
+ if (const Record *ElemRecord = ElemDesc->ElemRecord) {
+ if (const CXXDestructorDecl *Dtor = ElemRecord->getDestructor();
+ !Dtor || Dtor->isTrivial())
+ return true;
+ }
+
+ for (ssize_t I = Desc->getNumElems() - 1; I >= 0; --I) {
+ if (!this->emitConstUint64(I, SourceInfo{}))
+ return false;
+ if (!this->emitArrayElemPtrUint64(SourceInfo{}))
+ return false;
+ if (!this->emitDestruction(ElemDesc))
+ return false;
+ if (!this->emitPopPtr(SourceInfo{}))
+ return false;
+ }
+ return true;
+ }
- // Remove the instance pointer.
- return this->emitPopPtr(SourceInfo{});
+ assert(Desc->ElemRecord);
+ return this->emitRecordDestruction(Desc->ElemRecord);
}
namespace clang {
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h
index eeb56dc8456565..abaf28ac7d447d 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -289,7 +289,8 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
bool emitComplexReal(const Expr *SubExpr);
- bool emitRecordDestruction(const Descriptor *Desc);
+ bool emitRecordDestruction(const Record *R);
+ bool emitDestruction(const Descriptor *Desc);
unsigned collectBaseOffset(const RecordType *BaseType,
const RecordType *DerivedType);
@@ -401,7 +402,8 @@ template <class Emitter> class LocalScope : public VariableScope<Emitter> {
for (Scope::Local &Local : this->Ctx->Descriptors[*Idx]) {
if (!Local.Desc->isPrimitive() && !Local.Desc->isPrimitiveArray()) {
this->Ctx->emitGetPtrLocal(Local.Offset, SourceInfo{});
- this->Ctx->emitRecordDestruction(Local.Desc);
+ this->Ctx->emitDestruction(Local.Desc);
+ this->Ctx->emitPopPtr(SourceInfo{});
removeIfStoredOpaqueValue(Local);
}
}
More information about the cfe-commits
mailing list