Skip to content

Commit 00cdaa5

Browse files
authored
[clang][bytecode] Add Descriptor::hasTrivialDtor() (#146286)
We sometimes used to have a long list of ``` GetLocalPtr PopPtr [...] ``` ops at the end of scopes, because we first got a pointer to a local variable and only then did we figure out that we didn't actually want to call the destructor for it. Add a new function that allows us to just ask the `Descriptor` whether we need to call its destructor.
1 parent 53102a3 commit 00cdaa5

File tree

3 files changed

+27
-9
lines changed

3 files changed

+27
-9
lines changed

clang/lib/AST/ByteCode/Compiler.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -574,17 +574,17 @@ template <class Emitter> class LocalScope : public VariableScope<Emitter> {
574574
// Emit destructor calls for local variables of record
575575
// type with a destructor.
576576
for (Scope::Local &Local : llvm::reverse(this->Ctx->Descriptors[*Idx])) {
577-
if (!Local.Desc->isPrimitive() && !Local.Desc->isPrimitiveArray()) {
578-
if (!this->Ctx->emitGetPtrLocal(Local.Offset, E))
579-
return false;
577+
if (Local.Desc->hasTrivialDtor())
578+
continue;
579+
if (!this->Ctx->emitGetPtrLocal(Local.Offset, E))
580+
return false;
580581

581-
if (!this->Ctx->emitDestruction(Local.Desc, Local.Desc->getLoc()))
582-
return false;
582+
if (!this->Ctx->emitDestruction(Local.Desc, Local.Desc->getLoc()))
583+
return false;
583584

584-
if (!this->Ctx->emitPopPtr(E))
585-
return false;
586-
removeIfStoredOpaqueValue(Local);
587-
}
585+
if (!this->Ctx->emitPopPtr(E))
586+
return false;
587+
removeIfStoredOpaqueValue(Local);
588588
}
589589
return true;
590590
}

clang/lib/AST/ByteCode/Descriptor.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,21 @@ SourceInfo Descriptor::getLoc() const {
502502
llvm_unreachable("Invalid descriptor type");
503503
}
504504

505+
bool Descriptor::hasTrivialDtor() const {
506+
if (isPrimitive() || isPrimitiveArray() || isDummy())
507+
return true;
508+
509+
if (isRecord()) {
510+
assert(ElemRecord);
511+
const CXXDestructorDecl *Dtor = ElemRecord->getDestructor();
512+
return !Dtor || Dtor->isTrivial();
513+
}
514+
515+
// Composite arrays.
516+
assert(ElemDesc);
517+
return ElemDesc->hasTrivialDtor();
518+
}
519+
505520
bool Descriptor::isUnion() const { return isRecord() && ElemRecord->isUnion(); }
506521

507522
InitMap::InitMap(unsigned N)

clang/lib/AST/ByteCode/Descriptor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,9 @@ struct Descriptor final {
281281
/// Checks if this is a dummy descriptor.
282282
bool isDummy() const { return IsDummy; }
283283

284+
/// Whether variables of this descriptor need their destructor called or not.
285+
bool hasTrivialDtor() const;
286+
284287
void dump() const;
285288
void dump(llvm::raw_ostream &OS) const;
286289
void dumpFull(unsigned Offset = 0, unsigned Indent = 0) const;

0 commit comments

Comments
 (0)