diff --git a/oscar64/Constexpr.cpp b/oscar64/Constexpr.cpp index 134e477..1a5b83d 100644 --- a/oscar64/Constexpr.cpp +++ b/oscar64/Constexpr.cpp @@ -570,7 +570,8 @@ Expression* ConstexprInterpreter::EvalCall(Expression* exp) else if (pex->mType == EX_VARIABLE && (pex->mDecValue->mFlags & DTF_CONST)) { mParams[pos] = Value(pex->mLocation, pex->mDecValue->mBase); - mParams[pos].PutConst(0, pex->mDecValue->mValue->mDecValue); + if (pex->mDecValue->mSize > 0) + mParams[pos].PutConst(0, pex->mDecValue->mValue->mDecValue); } else return exp; diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index 2b56ef5..663ba6b 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -1095,9 +1095,14 @@ const Ident* Declaration::MangleIdent(void) Declaration* dec = mParams; while (dec) { - const Ident* id = dec->mBase->MangleIdent(); + const Ident* id; + if (dec->mBase) + id = dec->mBase->MangleIdent(); + else + id = dec->MangleIdent(); if (id) mMangleIdent = mMangleIdent->Mangle(id->mString); + dec = dec->mNext; if (dec) mMangleIdent = mMangleIdent->Mangle(","); @@ -1178,6 +1183,15 @@ 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; + } + while (pexp) { Expression* ex = pexp; @@ -1201,7 +1215,7 @@ bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec) } Declaration* ppdec = nullptr; - Declaration* ptdec = tdec->mTemplate->mParams; + ptdec = tdec->mTemplate->mParams; while (ptdec) { Declaration* pdec = mScope->Lookup(ptdec->mIdent); @@ -1785,6 +1799,8 @@ bool Declaration::IsSameParams(const Declaration* dec) const if (ld->mValue != rd->mValue) return false; } + else if (ld->mType == DT_TYPE_TEMPLATE || ld->mType == DT_CONST_TEMPLATE) + return false; else if (!ld->mBase->IsSame(rd->mBase)) return false; ld = ld->mNext; diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index ddd5401..f68964f 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -4836,7 +4836,7 @@ Expression* Parser::ParseLambdaExpression(void) vdec->mBase = cdec; vdec->mVarIndex = mLocalIndex++; vdec->mSize = cdec->mSize; - vdec->mFlags |= DTF_DEFINED; + vdec->mFlags |= DTF_DEFINED | DTF_CONST; vdec->mIdent = cdec->mIdent; Expression* vexp = new Expression(mScanner->mLocation, EX_VARIABLE); @@ -8365,6 +8365,25 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp Declaration* ppdec = nullptr; Declaration* pdec = tmpld->mParams; + + // Carry over already specialized parameters + while (pdec && (pdec->mType != DT_TYPE_TEMPLATE && pdec->mType != DT_CONST_TEMPLATE)) + { + Declaration* epdec = pdec->Clone(); + + tdec->mScope->Insert(epdec->mIdent, epdec->mBase); + epdec->mFlags |= DTF_DEFINED; + + if (ppdec) + ppdec->mNext = epdec; + else + tdec->mParams = epdec; + ppdec = epdec; + + pdec = pdec->mNext; + } + + // Now to the new parameters while (pdec) { Declaration* epdec = pdec->Clone(); @@ -8382,7 +8401,7 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp epdec->mBase = TheVoidTypeDeclaration; } } - else + else if (epdec->mType == DT_CONST_TEMPLATE) { if (exp->mType == EX_CONSTANT && (exp->mDecValue->mType == DT_CONST_INTEGER || exp->mDecValue->mType == DT_CONST_TEMPLATE)) epdec->mBase = exp->mDecValue; @@ -8400,13 +8419,25 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp ppdec = epdec; pdec = pdec->mNext; - if (pdec) - ConsumeToken(TK_COMMA); + if (pdec && !ConsumeTokenIf(TK_COMMA)) + break; } ConsumeToken(TK_GREATER_THAN); + + // Partial template arguments given + if (pdec) + { + if (ppdec) + ppdec->mNext = pdec; + else + tdec->mParams = pdec; + } } + while (!tmpld->mTokens) + tmpld = tmpld->mNext; + Declaration* etdec = tmpld->mNext; while (etdec && !etdec->IsSameParams(tdec)) etdec = etdec->mNext; @@ -8417,16 +8448,16 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp else { Declaration* epdec = tdec->mParams; - while (epdec && epdec->mBase->mType != DT_TYPE_TEMPLATE && epdec->mBase->mType != DT_CONST_TEMPLATE) + while (epdec && epdec->mBase && epdec->mBase->mType != DT_TYPE_TEMPLATE && epdec->mBase->mType != DT_CONST_TEMPLATE) epdec = epdec->mNext; if (epdec) { // Partial template specification - Declaration * bdec = new Declaration(mScanner->mLocation, DT_TYPE_STRUCT); + Declaration * bdec = new Declaration(mScanner->mLocation, tmpld->mBase->mType); tdec->mBase = bdec; bdec->mTemplate = tdec; - bdec->mBase = tmpld->mBase; + bdec->mBase = tmpld->mBase->mBase; tdec->mNext = tmpld; bdec->mIdent = tdec->MangleIdent();