aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/ExpressionGen.cc
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-18 06:09:01 +0000
committer_ov4 <ov4@ov4.org>2026-10-18 06:09:01 +0000
commitb17f101cfc75565f9991c856ec62f1e17b0ab104 (patch)
tree6c925f06c45dbaa557a0451cfca33f17be71ec67 /lib/CodeGen/ExpressionGen.cc
parent16231050058131860f710073c17d3bca7c6637eb (diff)
feat(operators): add member and unary overloads with explicit calls
Select member and global candidates together, enforce private access, and reuse argument marshalling. Materialize temporary receivers for chaining and register them for the existing object cleanup mechanism. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'lib/CodeGen/ExpressionGen.cc')
-rw-r--r--lib/CodeGen/ExpressionGen.cc22
1 files changed, 21 insertions, 1 deletions
diff --git a/lib/CodeGen/ExpressionGen.cc b/lib/CodeGen/ExpressionGen.cc
index 8fb13c9..a01cab2 100644
--- a/lib/CodeGen/ExpressionGen.cc
+++ b/lib/CodeGen/ExpressionGen.cc
@@ -73,6 +73,16 @@ Value *CodeGen::emitExpr(ExprAST *Expr) {
}
if (auto *Unary = dynamic_cast<UnaryExprAST*>(Expr)) {
+ if (isWholeArrayVar(Unary->getOperand())) {
+ reportError("A whole array cannot be used as an operand; index it");
+ return nullptr;
+ }
+ auto Overload = resolveOperator(Unary->getOp(), getExprTypeInfo(Unary->getOperand()));
+ if (Overload.Ambiguous) {
+ reportError("Ambiguous overload for %s", operatorName(Unary->getOp()).c_str());
+ return nullptr;
+ }
+ if (Overload.Signature) return emitOperatorCall(*Overload.Signature, Unary->getOperand());
if (Unary->getOp() == tok_not) {
const TypeInfo *Info = getExprTypeInfo(Unary->getOperand());
Value *Operand = Info && Info->isC()
@@ -123,6 +133,16 @@ Value *CodeGen::emitExpr(ExprAST *Expr) {
// '&' path: their admissible operations are decided by name here.
const TypeInfo *LT = getExprTypeInfo(Bin->getLHS());
const TypeInfo *RT = getExprTypeInfo(Bin->getRHS());
+ if (LT && RT) {
+ auto Overload = resolveOperator(Bin->getOp(), LT, RT);
+ if (Overload.Ambiguous) {
+ reportError("Ambiguous overload for %s(%s, %s)", operatorName(Bin->getOp()).c_str(),
+ LT->Name.c_str(), RT->Name.c_str());
+ return nullptr;
+ }
+ if (Overload.Signature)
+ return emitOperatorCall(*Overload.Signature, Bin->getLHS(), Bin->getRHS());
+ }
Value *L = emitExpr(Bin->getLHS());
Value *R = emitExpr(Bin->getRHS());
return emitBinaryOp(Bin->getOp(), L, LT, R, RT, Bin->getLine());
@@ -165,7 +185,7 @@ Value *CodeGen::emitBinaryOp(int Op, Value *L, const TypeInfo *LT,
reportError("Ambiguous overload for %s(%s, %s)", operatorName(Op).c_str(), LT->Name.c_str(), RT->Name.c_str());
return nullptr;
}
- if (Overload.Signature) return FuncGen->emitCall(*Overload.Signature, {L, R});
+ if (Overload.Signature) return emitOperatorValues(*Overload.Signature, L, LT, R);
if ((LT && LT->isC()) || (RT && RT->isC()))
return emitCBinaryOp(Op, L, LT, R, RT, Line);
if ((LT && LT->isUserKind()) || (RT && RT->isUserKind()))