aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/OperatorGen.cc
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-18 08:07:50 +0000
committer_ov4 <ov4@ov4.org>2026-10-18 08:07:50 +0000
commit345e3d419eafb0e234aecb4a33f37efe2afbbf53 (patch)
tree9330322103f26f15c6df91cbbd62bf5a1f6e72da /lib/CodeGen/OperatorGen.cc
parent927e3fc0384c941f9ad313a28768660c3cdb1777 (diff)
feat(classes): add copy constructors and statement-scoped temporaries
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'lib/CodeGen/OperatorGen.cc')
-rw-r--r--lib/CodeGen/OperatorGen.cc26
1 files changed, 22 insertions, 4 deletions
diff --git a/lib/CodeGen/OperatorGen.cc b/lib/CodeGen/OperatorGen.cc
index d340ed7..b449ba1 100644
--- a/lib/CodeGen/OperatorGen.cc
+++ b/lib/CodeGen/OperatorGen.cc
@@ -45,6 +45,7 @@ Value *CodeGen::materializeOperatorReceiver(Value *Val, const TypeInfo *Type) {
size_t Object = registerStackObject(Storage, Type->Name, DiagnosticLine, false, true);
Builder->CreateStore(Val, Storage);
activateStackObject(Object);
+ if (Object != size_t(-1)) StackObjects[Object].Temporary = true;
return Storage;
}
@@ -76,8 +77,25 @@ Value *CodeGen::emitOperatorCall(const FuncSig &Signature, ExprAST *Left, ExprAS
Value *CodeGen::emitOperatorValues(const FuncSig &Signature, Value *Left,
const TypeInfo *LeftType, Value *Right) {
if (!checkOperatorAccess(Signature)) return nullptr;
- if (!Signature.Prototype->getOwnerClass().empty())
- Left = materializeOperatorReceiver(Left, LeftType);
- if (!Left) return nullptr;
- return FuncGen->emitCall(Signature, {Left, Right});
+ bool Member = !Signature.Prototype->getOwnerClass().empty();
+ std::vector<Value *> Args;
+ std::vector<size_t> Transfers;
+ auto Capture = [&](Value *Val, const TypeInfo *Type) -> Value * {
+ auto *Slot = CreateEntryBlockAlloca(Builder->GetInsertBlock()->getParent(),
+ Type->LLVMType, "case_operand");
+ Builder->CreateStore(Val, Slot);
+ return Slot;
+ };
+ if (Member) Args.push_back(Capture(Left, LeftType));
+ else {
+ if (LeftType->IsClass) Left = copyClassValue(LeftType, Capture(Left, LeftType), Transfers);
+ if (!Left) return nullptr;
+ Args.push_back(Left);
+ }
+ const TypeInfo *RightType = resolveType(Signature.Params[Member ? 0 : 1].TypeName);
+ if (RightType->IsClass) Right = copyClassValue(RightType, Capture(Right, RightType), Transfers);
+ if (!Right) return nullptr;
+ Args.push_back(Right);
+ transferObjects(Transfers);
+ return FuncGen->emitCall(Signature, Args);
}