aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGen.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/CodeGen.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/CodeGen.cc')
-rw-r--r--lib/CodeGen/CodeGen.cc24
1 files changed, 23 insertions, 1 deletions
diff --git a/lib/CodeGen/CodeGen.cc b/lib/CodeGen/CodeGen.cc
index c9d8c1a..49fc7b1 100644
--- a/lib/CodeGen/CodeGen.cc
+++ b/lib/CodeGen/CodeGen.cc
@@ -390,6 +390,7 @@ bool CodeGen::marshalCallArgs(const FuncSig &Signature,
return false;
}
+ std::vector<size_t> Transfers;
for (size_t i = 0; i < ArgExprs.size(); ++i) {
if (i >= Sig->Params.size()) {
Value *V = emitVariadicArgument(ArgExprs[i], Callee, i + 1);
@@ -423,6 +424,26 @@ bool CodeGen::marshalCallArgs(const FuncSig &Signature,
if (IsByRef) {
auto *Var = dynamic_cast<VariableExprAST*>(ArgExpr);
+ bool InternalBinding = Signature.Prototype &&
+ (sameIdentifier(Signature.Prototype->getName(), "NEW") ||
+ Signature.Prototype->getOperator() == tok_assign);
+ if (!Var && InternalBinding) {
+ const TypeInfo *Actual = getExprTypeInfo(ArgExpr);
+ if (!Actual || !Actual->sameType(resolveType(TypeName))) {
+ reportError("BYREF argument to %s has an incompatible type", Callee.c_str());
+ return false;
+ }
+ if (isObjectLValue(ArgExpr)) {
+ LValueInfo LV;
+ if (!emitLValue(ArgExpr, LV)) return false;
+ Out.push_back(LV.Addr);
+ } else {
+ Value *Storage = materializeOperatorReceiver(emitExpr(ArgExpr), Actual);
+ if (!Storage) return false;
+ Out.push_back(Storage);
+ }
+ continue;
+ }
if (!Var) {
reportError("BYREF argument to %s must be a variable", Callee.c_str());
return false;
@@ -442,11 +463,12 @@ bool CodeGen::marshalCallArgs(const FuncSig &Signature,
}
Out.push_back(symbolAddress(*Info));
} else {
- Value *V = emitCoercedExpr(ArgExpr, resolveType(TypeName));
+ Value *V = emitOwnedValue(ArgExpr, resolveType(TypeName), Transfers);
if (!V) return false;
Out.push_back(V);
}
}
+ transferObjects(Transfers);
return true;
}