summaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
authorTimm Baeder <tbaeder@redhat.com>2025-06-30 16:59:57 +0200
committerGitHub <noreply@github.com>2025-06-30 16:59:57 +0200
commit00cdaa5c395c122f8ede2a4b0587bf9a0dfecc2a (patch)
tree53681e3d133c3951d31888f03ebed4a8e53fb041 /clang
parent53102a395f3bd07762c183c9ecd213a4759559dd (diff)
[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.
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/AST/ByteCode/Compiler.h18
-rw-r--r--clang/lib/AST/ByteCode/Descriptor.cpp15
-rw-r--r--clang/lib/AST/ByteCode/Descriptor.h3
3 files changed, 27 insertions, 9 deletions
diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h
index a1d068cc7e0a..1a5fd8678587 100644
--- a/clang/lib/AST/ByteCode/Compiler.h
+++ b/clang/lib/AST/ByteCode/Compiler.h
@@ -574,17 +574,17 @@ public:
// Emit destructor calls for local variables of record
// type with a destructor.
for (Scope::Local &Local : llvm::reverse(this->Ctx->Descriptors[*Idx])) {
- if (!Local.Desc->isPrimitive() && !Local.Desc->isPrimitiveArray()) {
- if (!this->Ctx->emitGetPtrLocal(Local.Offset, E))
- return false;
+ if (Local.Desc->hasTrivialDtor())
+ continue;
+ if (!this->Ctx->emitGetPtrLocal(Local.Offset, E))
+ return false;
- if (!this->Ctx->emitDestruction(Local.Desc, Local.Desc->getLoc()))
- return false;
+ if (!this->Ctx->emitDestruction(Local.Desc, Local.Desc->getLoc()))
+ return false;
- if (!this->Ctx->emitPopPtr(E))
- return false;
- removeIfStoredOpaqueValue(Local);
- }
+ if (!this->Ctx->emitPopPtr(E))
+ return false;
+ removeIfStoredOpaqueValue(Local);
}
return true;
}
diff --git a/clang/lib/AST/ByteCode/Descriptor.cpp b/clang/lib/AST/ByteCode/Descriptor.cpp
index 46e4d0d940b3..c89eca9bef44 100644
--- a/clang/lib/AST/ByteCode/Descriptor.cpp
+++ b/clang/lib/AST/ByteCode/Descriptor.cpp
@@ -502,6 +502,21 @@ SourceInfo Descriptor::getLoc() const {
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(); }
InitMap::InitMap(unsigned N)
diff --git a/clang/lib/AST/ByteCode/Descriptor.h b/clang/lib/AST/ByteCode/Descriptor.h
index f25ad8f4c758..4591eabb69bb 100644
--- a/clang/lib/AST/ByteCode/Descriptor.h
+++ b/clang/lib/AST/ByteCode/Descriptor.h
@@ -281,6 +281,9 @@ public:
/// Checks if this is a dummy descriptor.
bool isDummy() const { return IsDummy; }
+ /// Whether variables of this descriptor need their destructor called or not.
+ bool hasTrivialDtor() const;
+
void dump() const;
void dump(llvm::raw_ostream &OS) const;
void dumpFull(unsigned Offset = 0, unsigned Indent = 0) const;