aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/ConstructorGen.cc
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-30 14:23:32 +0000
committer_ov4 <ov4@ov4.org>2026-10-30 14:23:32 +0000
commit4cb0d9b196008bc55dbfcdac1f9211dbbc879895 (patch)
tree0d95a2682ef26455483c4bb9222e1dff0d5c8e69 /lib/CodeGen/ConstructorGen.cc
parent63109537383fa58c6a1db95f275d6b5de63b0015 (diff)
feat(types): support implicit single-argument constructors
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'lib/CodeGen/ConstructorGen.cc')
-rw-r--r--lib/CodeGen/ConstructorGen.cc13
1 files changed, 10 insertions, 3 deletions
diff --git a/lib/CodeGen/ConstructorGen.cc b/lib/CodeGen/ConstructorGen.cc
index da89f59..81c448f 100644
--- a/lib/CodeGen/ConstructorGen.cc
+++ b/lib/CodeGen/ConstructorGen.cc
@@ -24,9 +24,9 @@ Value *CodeGen::emitOwnedValue(ExprAST *Expr, const TypeInfo *Type,
const TypeInfo *Source = getExprTypeInfo(Expr);
// A CHAR argument becomes a fresh STRING temporary, owned like any other.
bool FromChar = Source && Type->isString() && Source->Kind == TypeKind::Char;
- if (!Source || (!Source->sameType(Type) && !FromChar)) return emitCoercedExpr(Expr, Type);
+ if (!Source) return emitCoercedExpr(Expr, Type);
Value *Value = nullptr;
- if (!FromChar && isObjectLValue(Expr)) {
+ if (!FromChar && Source->sameType(Type) && isObjectLValue(Expr)) {
LValueInfo LV;
const auto *Var = dynamic_cast<VariableExprAST *>(Expr);
const auto *Symbol = Var ? getSymbolInfo(Var->getName()) : nullptr;
@@ -241,7 +241,14 @@ void CodeGen::emitAssignment(const LValueInfo &Target, ExprAST *Expr, const Symb
return;
}
Value *Val = emitCoercedExpr(Expr, Info);
- if (Val) Builder->CreateStore(Val, Target.Addr);
+ if (Val && Info && Info->IsClass && ExprType && !ExprType->sameType(Info)) {
+ materializeOperatorReceiver(Val, Info);
+ std::vector<size_t> Transfers;
+ if (typeNeedsDestruction(Info->Name)) Transfers.push_back(StackObjects.size() - 1);
+ if (!emitDestroy(Info->Name, Target.Addr, DiagnosticLine)) return;
+ Builder->CreateStore(Val, Target.Addr);
+ transferObjects(Transfers);
+ } else if (Val) Builder->CreateStore(Val, Target.Addr);
}
bool CodeGen::typeNeedsDestruction(const std::string &TypeName) const {