aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/ConstructorGen.cc
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-17 08:32:43 +0000
committer_ov4 <ov4@ov4.org>2026-10-17 08:32:43 +0000
commit59e3c50bcd58130e81e1f57b21d6e57b4d4aba6d (patch)
treec5f6c5b1bd367feadca0c2e7d0f47c8dedb91b20 /lib/CodeGen/ConstructorGen.cc
parente847e4c53cf21fcb96f7ed7765e305a7ec8e6c19 (diff)
feat(classes): destroy and release heap objects with DELETE
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'lib/CodeGen/ConstructorGen.cc')
-rw-r--r--lib/CodeGen/ConstructorGen.cc27
1 files changed, 27 insertions, 0 deletions
diff --git a/lib/CodeGen/ConstructorGen.cc b/lib/CodeGen/ConstructorGen.cc
index 99f21df..9e6b0b3 100644
--- a/lib/CodeGen/ConstructorGen.cc
+++ b/lib/CodeGen/ConstructorGen.cc
@@ -80,3 +80,30 @@ void CodeGen::emitAssignment(const LValueInfo &Target, ExprAST *Expr, const Symb
Value *Val = emitCoercedExpr(Expr, Info);
if (Val) Builder->CreateStore(Val, Target.Addr);
}
+
+bool CodeGen::typeNeedsDestruction(const std::string &TypeName) const {
+ if (findMethod(TypeName, "DELETE")) return true;
+ const TypeInfo *Info = resolveType(TypeName);
+ if (Info && Info->asRecord()) {
+ for (const auto &[Name, Field] : Info->Record.Fields)
+ if (typeNeedsDestruction(Field.TypeName)) return true;
+ }
+ return false;
+}
+
+bool CodeGen::emitDestroy(const std::string &TypeName, Value *Addr, int Line) {
+ SaveAndRestore<int> Location(DiagnosticLine, Line);
+ const TypeInfo *Info = resolveType(TypeName);
+ if (!Info) return false;
+ if (findMethod(TypeName, "DELETE") &&
+ !emitMethodCall(TypeName, Addr, "DELETE", {}, Line)) return false;
+ if (Info->asRecord()) {
+ for (auto It = Info->Record.Fields.rbegin(); It != Info->Record.Fields.rend(); ++It) {
+ const auto &Field = It->second;
+ if (!typeNeedsDestruction(Field.TypeName)) continue;
+ Value *FieldAddr = Builder->CreateStructGEP(Info->LLVMType, Addr, Field.Index);
+ if (!emitDestroy(Field.TypeName, FieldAddr, Line)) return false;
+ }
+ }
+ return true;
+}