Improve function automatic template matching

This commit is contained in:
drmortalwombat 2025-05-01 16:04:10 +02:00
parent 347898ea53
commit 4ee6ca5b94
3 changed files with 43 additions and 29 deletions

View File

@ -1554,6 +1554,7 @@ const Ident* Declaration::FullIdent(void)
Declaration* dec = mBase->mParams; Declaration* dec = mBase->mParams;
while (dec) while (dec)
{ {
if (dec->mBase->mIdent)
tident = tident->Mangle(dec->mBase->MangleIdent()->mString); tident = tident->Mangle(dec->mBase->MangleIdent()->mString);
dec = dec->mNext; dec = dec->mNext;
if (dec) if (dec)
@ -1697,8 +1698,10 @@ const Ident* Declaration::MangleIdent(void)
else else
mMangleIdent = Ident::Unique("void"); mMangleIdent = Ident::Unique("void");
} }
else else if (mQualIdent)
mMangleIdent = mQualIdent; mMangleIdent = mQualIdent;
else
mMangleIdent = mIdent;
if (mTemplate) if (mTemplate)
{ {
@ -1769,19 +1772,8 @@ Declaration* Declaration::ExpandTemplate(DeclarationScope* scope)
return this; return this;
} }
bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec) bool Declaration::ResolveTemplateParameterList(Expression* pexp, Declaration* pdec, bool preliminary)
{ {
Declaration* pdec = tdec->mBase->mParams;
// Insert partially resolved templates
Declaration* ptdec = tdec->mTemplate->mParams;
while (ptdec)
{
if (ptdec->mBase)
mScope->Insert(ptdec->mIdent, ptdec->mBase);
ptdec = ptdec->mNext;
}
Declaration* phead = nullptr, * ptail = nullptr; Declaration* phead = nullptr, * ptail = nullptr;
int pcnt = 0; int pcnt = 0;
@ -1817,7 +1809,7 @@ bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec)
} }
else else
{ {
if (!ResolveTemplate(ex->mDecType, pdec->mBase)) if (!ResolveTemplate(ex->mDecType, pdec->mBase, false, preliminary))
return false; return false;
pdec = pdec->mNext; pdec = pdec->mNext;
@ -1844,6 +1836,25 @@ bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec)
return false; return false;
} }
return true;
}
bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec)
{
Declaration* pdec = tdec->mBase->mParams;
// Insert partially resolved templates
Declaration* ptdec = tdec->mTemplate->mParams;
while (ptdec)
{
if (ptdec->mBase)
mScope->Insert(ptdec->mIdent, ptdec->mBase);
ptdec = ptdec->mNext;
}
if (!ResolveTemplateParameterList(pexp, pdec, true) || !ResolveTemplateParameterList(pexp, pdec, false))
return false;
Declaration* ppdec = nullptr; Declaration* ppdec = nullptr;
ptdec = tdec->mTemplate->mParams; ptdec = tdec->mTemplate->mParams;
while (ptdec) while (ptdec)
@ -1886,7 +1897,7 @@ bool Declaration::CanResolveTemplate(Expression* pexp, Declaration* tdec)
if (pdec) if (pdec)
{ {
if (!ResolveTemplate(ex->mDecType, pdec->mBase)) if (!ResolveTemplate(ex->mDecType, pdec->mBase, false, false))
return false; return false;
if (pdec->mType != DT_PACK_ARGUMENT) if (pdec->mType != DT_PACK_ARGUMENT)
@ -1902,19 +1913,19 @@ bool Declaration::CanResolveTemplate(Expression* pexp, Declaration* tdec)
return true; return true;
} }
bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec) bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec, bool same, bool preliminary)
{ {
if (tdec->IsSame(fdec)) if (tdec->IsSame(fdec))
return true; return true;
else if (fdec->IsReference()) else if (fdec->IsReference())
return ResolveTemplate(fdec->mBase, tdec); return ResolveTemplate(fdec->mBase, tdec, same, preliminary);
else if (tdec->mType == DT_TYPE_FUNCTION) else if (tdec->mType == DT_TYPE_FUNCTION)
{ {
if (fdec->mType == DT_TYPE_FUNCTION) if (fdec->mType == DT_TYPE_FUNCTION)
{ {
if (fdec->mBase) if (fdec->mBase)
{ {
if (!tdec->mBase || !ResolveTemplate(fdec->mBase, tdec->mBase)) if (!tdec->mBase || !ResolveTemplate(fdec->mBase, tdec->mBase, true, preliminary))
return false; return false;
} }
else if (tdec->mBase) else if (tdec->mBase)
@ -1953,7 +1964,7 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
if (!fpdec) if (!fpdec)
return false; return false;
if (!ResolveTemplate(fpdec->mBase, tpdec->mBase)) if (!ResolveTemplate(fpdec->mBase, tpdec->mBase, true, preliminary))
return false; return false;
fpdec = fpdec->mNext; fpdec = fpdec->mNext;
@ -1969,16 +1980,16 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
} }
else if (tdec->mType == DT_TYPE_REFERENCE) else if (tdec->mType == DT_TYPE_REFERENCE)
{ {
return ResolveTemplate(fdec, tdec->mBase); return ResolveTemplate(fdec, tdec->mBase, true, preliminary);
} }
else if (tdec->mType == DT_TYPE_RVALUEREF) else if (tdec->mType == DT_TYPE_RVALUEREF)
{ {
return ResolveTemplate(fdec, tdec->mBase); return ResolveTemplate(fdec, tdec->mBase, true, preliminary);
} }
else if (tdec->mType == DT_TYPE_POINTER) else if (tdec->mType == DT_TYPE_POINTER)
{ {
if (fdec->mType == DT_TYPE_POINTER || fdec->mType == DT_TYPE_ARRAY) if (fdec->mType == DT_TYPE_POINTER || fdec->mType == DT_TYPE_ARRAY)
return ResolveTemplate(fdec->mBase, tdec->mBase); return ResolveTemplate(fdec->mBase, tdec->mBase, true, preliminary);
else else
return false; return false;
} }
@ -1998,10 +2009,12 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
if (pdec->mType == DT_TYPE_STRUCT) if (pdec->mType == DT_TYPE_STRUCT)
pdec = pdec->mScope->Lookup(tdec->mIdent); pdec = pdec->mScope->Lookup(tdec->mIdent);
} }
else if (preliminary && !same)
return true;
else else
pdec = mScope->Insert(tdec->mIdent, fdec); pdec = mScope->Insert(tdec->mIdent, fdec);
if (pdec && !pdec->IsSame(fdec)) if (pdec && !(same ? pdec->IsSame(fdec) : pdec->CanAssign(fdec)))
return false; return false;
return true; return true;

View File

@ -361,8 +361,9 @@ public:
DecType ValueType(void) const; DecType ValueType(void) const;
bool CanResolveTemplate(Expression* pexp, Declaration* tdec); bool CanResolveTemplate(Expression* pexp, Declaration* tdec);
bool ResolveTemplate(Declaration* fdec, Declaration * tdec); bool ResolveTemplate(Declaration* fdec, Declaration * tdec, bool same, bool preliminary);
bool ResolveTemplate(Expression* pexp, Declaration* tdec); bool ResolveTemplate(Expression* pexp, Declaration* tdec);
bool ResolveTemplateParameterList(Expression* pexp, Declaration* pdec, bool preliminary);
Declaration* ExpandTemplate(DeclarationScope* scope); Declaration* ExpandTemplate(DeclarationScope* scope);

View File

@ -10845,10 +10845,10 @@ int Parser::ExpansionDistance(Declaration* tdec, Declaration* spec, Declaration*
{ {
if (ptdec->mBase) if (ptdec->mBase)
{ {
if (!xtdec->ResolveTemplate(psdec->mBase, ptdec->mBase)) if (!xtdec->ResolveTemplate(psdec->mBase, ptdec->mBase, true, false))
return NOOVERLOAD; return NOOVERLOAD;
} }
else if (!xtdec->ResolveTemplate(psdec->mBase, ptdec)) else if (!xtdec->ResolveTemplate(psdec->mBase, ptdec, true, false))
return NOOVERLOAD; return NOOVERLOAD;
else else
cost += 100; cost += 100;
@ -10872,7 +10872,7 @@ int Parser::ExpansionDistance(Declaration* tdec, Declaration* spec, Declaration*
} }
else if (psdec->mBase) else if (psdec->mBase)
{ {
if (!xtdec->ResolveTemplate(psdec->mBase, ptdec)) if (!xtdec->ResolveTemplate(psdec->mBase, ptdec, true, false))
return NOOVERLOAD; return NOOVERLOAD;
Declaration* dec = psdec->mBase->mParams; Declaration* dec = psdec->mBase->mParams;
@ -10892,7 +10892,7 @@ int Parser::ExpansionDistance(Declaration* tdec, Declaration* spec, Declaration*
} }
else if (psdec->mBase) else if (psdec->mBase)
{ {
if (!xtdec->ResolveTemplate(psdec->mBase, ptdec)) if (!xtdec->ResolveTemplate(psdec->mBase, ptdec, true, false))
return NOOVERLOAD; return NOOVERLOAD;
psdec = psdec->mNext; psdec = psdec->mNext;
cost += 200; cost += 200;