aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/FunctionGen.cc
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-28 13:36:16 +0000
committer_ov4 <ov4@ov4.org>2026-10-28 13:36:16 +0000
commitb28384fed1ce638e8b00b72dba974e9fd7e55eb4 (patch)
treeb0b342b148c1d5b33197f7a59d0a7a7edb92af1c /lib/CodeGen/FunctionGen.cc
parentcaa88a9b36d9e1dfae40ecb31aee05bc2891fa17 (diff)
feat(overload): support default return types
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'lib/CodeGen/FunctionGen.cc')
-rw-r--r--lib/CodeGen/FunctionGen.cc27
1 files changed, 27 insertions, 0 deletions
diff --git a/lib/CodeGen/FunctionGen.cc b/lib/CodeGen/FunctionGen.cc
index c162b46..a0c520d 100644
--- a/lib/CodeGen/FunctionGen.cc
+++ b/lib/CodeGen/FunctionGen.cc
@@ -113,9 +113,30 @@ const FuncSig *FunctionGen::getSignatureByLink(const std::string &Name) const {
return &Signatures.at(It->second.first)[It->second.second];
}
+// Defaults resolve only return-type ambiguity within one parameter signature.
+const FuncSig *FunctionGen::selectDefaultReturn(const std::vector<const FuncSig *> &Candidates) {
+ const FuncSig *Selected = nullptr;
+ for (const FuncSig *Sig : Candidates) {
+ if (!sameIdentifier(Sig->Name, Candidates.front()->Name) ||
+ !sameIdentifier(Sig->ParamKey, Candidates.front()->ParamKey)) return nullptr;
+ if (Sig->IsDefaultReturn) {
+ if (Selected) return nullptr;
+ Selected = Sig;
+ }
+ }
+ return Selected;
+}
+
// Copy-constructor, operator, MAIN and name-collision rules for a
// FUNCTION/PROCEDURE prototype; reports the first violation.
bool FunctionGen::validatePrototype(PrototypeAST *Proto) {
+ if (Proto->isDefaultReturn()) {
+ const TypeInfo *Return = Types.resolve(Proto->getReturnType());
+ if (!Proto->isOverload() || (Return && Return->isVoid())) {
+ reportError("DEFAULT requires a non-VOID OVERLOAD FUNCTION");
+ return false;
+ }
+ }
if (!Proto->getOwnerClass().empty() && sameIdentifier(Proto->getName(), "NEW") &&
Proto->getParams().size() == 1) {
const auto &P = Proto->getParams()[0];
@@ -192,6 +213,7 @@ Function *FunctionGen::emitPrototype(PrototypeAST *Proto) {
Sig.OwnerUnit = CurrentUnit;
Sig.Name = Proto->getLinkName();
Sig.IsOverload = Proto->isOverload();
+ Sig.IsDefaultReturn = Proto->isDefaultReturn();
Sig.Prototype = Proto;
Sig.ReturnTypeName = Proto->getReturnType();
@@ -247,6 +269,11 @@ Function *FunctionGen::emitPrototype(PrototypeAST *Proto) {
return nullptr;
}
if (sameIdentifier(Existing.ParamKey, Sig.ParamKey) &&
+ Existing.IsDefaultReturn && Sig.IsDefaultReturn) {
+ reportError("Duplicate DEFAULT return for %s(%s)", Sig.Name.c_str(), Sig.ParamKey.c_str());
+ return nullptr;
+ }
+ if (sameIdentifier(Existing.ParamKey, Sig.ParamKey) &&
sameIdentifier(Existing.ReturnKey, Sig.ReturnKey)) {
if (Existing.OwnerUnit != CurrentUnit)
reportError("Duplicate definition %s in %s and %s", Sig.Name.c_str(),