[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.
This commit is contained in:
parent
53102a395f
commit
00cdaa5c39
@ -574,17 +574,17 @@ public:
|
|||||||
// Emit destructor calls for local variables of record
|
// Emit destructor calls for local variables of record
|
||||||
// type with a destructor.
|
// type with a destructor.
|
||||||
for (Scope::Local &Local : llvm::reverse(this->Ctx->Descriptors[*Idx])) {
|
for (Scope::Local &Local : llvm::reverse(this->Ctx->Descriptors[*Idx])) {
|
||||||
if (!Local.Desc->isPrimitive() && !Local.Desc->isPrimitiveArray()) {
|
if (Local.Desc->hasTrivialDtor())
|
||||||
if (!this->Ctx->emitGetPtrLocal(Local.Offset, E))
|
continue;
|
||||||
return false;
|
if (!this->Ctx->emitGetPtrLocal(Local.Offset, E))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!this->Ctx->emitDestruction(Local.Desc, Local.Desc->getLoc()))
|
if (!this->Ctx->emitDestruction(Local.Desc, Local.Desc->getLoc()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!this->Ctx->emitPopPtr(E))
|
if (!this->Ctx->emitPopPtr(E))
|
||||||
return false;
|
return false;
|
||||||
removeIfStoredOpaqueValue(Local);
|
removeIfStoredOpaqueValue(Local);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -502,6 +502,21 @@ SourceInfo Descriptor::getLoc() const {
|
|||||||
llvm_unreachable("Invalid descriptor type");
|
llvm_unreachable("Invalid descriptor type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Descriptor::hasTrivialDtor() const {
|
||||||
|
if (isPrimitive() || isPrimitiveArray() || isDummy())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (isRecord()) {
|
||||||
|
assert(ElemRecord);
|
||||||
|
const CXXDestructorDecl *Dtor = ElemRecord->getDestructor();
|
||||||
|
return !Dtor || Dtor->isTrivial();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Composite arrays.
|
||||||
|
assert(ElemDesc);
|
||||||
|
return ElemDesc->hasTrivialDtor();
|
||||||
|
}
|
||||||
|
|
||||||
bool Descriptor::isUnion() const { return isRecord() && ElemRecord->isUnion(); }
|
bool Descriptor::isUnion() const { return isRecord() && ElemRecord->isUnion(); }
|
||||||
|
|
||||||
InitMap::InitMap(unsigned N)
|
InitMap::InitMap(unsigned N)
|
||||||
|
@ -281,6 +281,9 @@ public:
|
|||||||
/// Checks if this is a dummy descriptor.
|
/// Checks if this is a dummy descriptor.
|
||||||
bool isDummy() const { return IsDummy; }
|
bool isDummy() const { return IsDummy; }
|
||||||
|
|
||||||
|
/// Whether variables of this descriptor need their destructor called or not.
|
||||||
|
bool hasTrivialDtor() const;
|
||||||
|
|
||||||
void dump() const;
|
void dump() const;
|
||||||
void dump(llvm::raw_ostream &OS) const;
|
void dump(llvm::raw_ostream &OS) const;
|
||||||
void dumpFull(unsigned Offset = 0, unsigned Indent = 0) const;
|
void dumpFull(unsigned Offset = 0, unsigned Indent = 0) const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user