Struct function return value
This commit is contained in:
parent
815f64d14c
commit
19a54432f6
|
@ -1921,6 +1921,57 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
block->Append(fins);
|
block->Append(fins);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Declaration * decResult = nullptr;
|
||||||
|
|
||||||
|
if (ftype->mBase->mType == DT_TYPE_STRUCT)
|
||||||
|
{
|
||||||
|
int nindex = proc->mNumLocals++;
|
||||||
|
|
||||||
|
Declaration* vdec = new Declaration(exp->mLocation, DT_VARIABLE);
|
||||||
|
|
||||||
|
vdec->mVarIndex = nindex;
|
||||||
|
vdec->mBase = ftype->mBase;
|
||||||
|
vdec->mSize = ftype->mBase->mSize;
|
||||||
|
|
||||||
|
decResult = vdec;
|
||||||
|
|
||||||
|
InterInstruction* vins = new InterInstruction();
|
||||||
|
vins->mCode = IC_CONSTANT;
|
||||||
|
vins->mDst.mType = IT_POINTER;
|
||||||
|
vins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||||
|
vins->mConst.mMemory = IM_LOCAL;
|
||||||
|
vins->mConst.mVarIndex = nindex;
|
||||||
|
vins->mConst.mOperandSize = ftype->mBase->mSize;
|
||||||
|
block->Append(vins);
|
||||||
|
|
||||||
|
InterInstruction* ains = new InterInstruction();
|
||||||
|
ains->mCode = IC_CONSTANT;
|
||||||
|
ains->mDst.mType = IT_POINTER;
|
||||||
|
ains->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||||
|
ains->mConst.mVarIndex = 0;
|
||||||
|
ains->mConst.mIntConst = 0;
|
||||||
|
ains->mConst.mOperandSize = 2;
|
||||||
|
if (ftype->mFlags & DTF_FASTCALL)
|
||||||
|
ains->mConst.mMemory = IM_FPARAM;
|
||||||
|
else
|
||||||
|
ains->mConst.mMemory = IM_FRAME;
|
||||||
|
block->Append(ains);
|
||||||
|
|
||||||
|
InterInstruction* wins = new InterInstruction();
|
||||||
|
wins->mCode = IC_STORE;
|
||||||
|
wins->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
|
wins->mSrc[0].mType = IT_POINTER;
|
||||||
|
wins->mSrc[0].mTemp = vins->mDst.mTemp;
|
||||||
|
wins->mSrc[1].mType = IT_POINTER;
|
||||||
|
wins->mSrc[1].mTemp = ains->mDst.mTemp;
|
||||||
|
wins->mSrc[1].mOperandSize = 2;
|
||||||
|
block->Append(wins);
|
||||||
|
|
||||||
|
atotal = 2;
|
||||||
|
|
||||||
|
decResult = vdec;
|
||||||
|
}
|
||||||
|
|
||||||
if (exp->mLeft->mDecValue->mType == DT_CONST_FUNCTION)
|
if (exp->mLeft->mDecValue->mType == DT_CONST_FUNCTION)
|
||||||
proc->AddCalledFunction(proc->mModule->mProcedures[exp->mLeft->mDecValue->mVarIndex]);
|
proc->AddCalledFunction(proc->mModule->mProcedures[exp->mLeft->mDecValue->mVarIndex]);
|
||||||
else
|
else
|
||||||
|
@ -2058,7 +2109,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
cins->mCode = IC_CALL;
|
cins->mCode = IC_CALL;
|
||||||
cins->mSrc[0].mType = IT_POINTER;
|
cins->mSrc[0].mType = IT_POINTER;
|
||||||
cins->mSrc[0].mTemp = vl.mTemp;
|
cins->mSrc[0].mTemp = vl.mTemp;
|
||||||
if (ftype->mBase->mType != DT_TYPE_VOID)
|
if (ftype->mBase->mType != DT_TYPE_VOID && ftype->mBase->mType != DT_TYPE_STRUCT)
|
||||||
{
|
{
|
||||||
cins->mDst.mType = InterTypeOf(ftype->mBase);
|
cins->mDst.mType = InterTypeOf(ftype->mBase);
|
||||||
cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType);
|
cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType);
|
||||||
|
@ -2081,6 +2132,19 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
block->Append(xins);
|
block->Append(xins);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (decResult)
|
||||||
|
{
|
||||||
|
InterInstruction* vins = new InterInstruction();
|
||||||
|
vins->mCode = IC_CONSTANT;
|
||||||
|
vins->mDst.mType = IT_POINTER;
|
||||||
|
vins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||||
|
vins->mConst.mMemory = IM_LOCAL;
|
||||||
|
vins->mConst.mVarIndex = decResult->mVarIndex;
|
||||||
|
block->Append(vins);
|
||||||
|
|
||||||
|
return ExValue(ftype->mBase, vins->mDst.mTemp, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
return ExValue(ftype->mBase, cins->mDst.mTemp);
|
return ExValue(ftype->mBase, cins->mDst.mTemp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2168,6 +2232,54 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
if (exp->mLeft)
|
if (exp->mLeft)
|
||||||
{
|
{
|
||||||
vr = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper);
|
vr = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper);
|
||||||
|
|
||||||
|
if (procType->mBase->mType == DT_TYPE_STRUCT)
|
||||||
|
{
|
||||||
|
vr = Dereference(proc, block, vr, 1);
|
||||||
|
|
||||||
|
if (!procType->mBase || procType->mBase->mType == DT_TYPE_VOID)
|
||||||
|
mErrors->Error(exp->mLocation, EERR_INVALID_RETURN, "Function has void return type");
|
||||||
|
else if (!procType->mBase->CanAssign(vr.mType))
|
||||||
|
mErrors->Error(exp->mLocation, EERR_INVALID_RETURN, "Cannot return incompatible type");
|
||||||
|
else if (vr.mReference != 1)
|
||||||
|
mErrors->Error(exp->mLocation, EERR_INVALID_RETURN, "Non addressable object");
|
||||||
|
|
||||||
|
InterInstruction* ains = new InterInstruction();
|
||||||
|
ains->mCode = IC_CONSTANT;
|
||||||
|
ains->mDst.mType = IT_POINTER;
|
||||||
|
ains->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||||
|
ains->mConst.mVarIndex = 0;
|
||||||
|
ains->mConst.mIntConst = 0;
|
||||||
|
ains->mConst.mOperandSize = 2;
|
||||||
|
if (procType->mFlags & DTF_FASTCALL)
|
||||||
|
ains->mConst.mMemory = IM_FPARAM;
|
||||||
|
else
|
||||||
|
ains->mConst.mMemory = IM_PARAM;
|
||||||
|
block->Append(ains);
|
||||||
|
|
||||||
|
InterInstruction* rins = new InterInstruction();
|
||||||
|
rins->mCode = IC_LOAD;
|
||||||
|
rins->mSrc[0].mMemory = IM_INDIRECT;
|
||||||
|
rins->mSrc[0].mType = IT_POINTER;
|
||||||
|
rins->mSrc[0].mTemp = ains->mDst.mTemp;
|
||||||
|
rins->mDst.mType = IT_POINTER;
|
||||||
|
rins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||||
|
block->Append(rins);
|
||||||
|
|
||||||
|
InterInstruction* cins = new InterInstruction();
|
||||||
|
cins->mCode = IC_COPY;
|
||||||
|
cins->mConst.mMemory = IM_INDIRECT;
|
||||||
|
cins->mSrc[0].mType = IT_POINTER;
|
||||||
|
cins->mSrc[0].mTemp = vr.mTemp;
|
||||||
|
cins->mSrc[1].mType = IT_POINTER;
|
||||||
|
cins->mSrc[1].mTemp = rins->mDst.mTemp;
|
||||||
|
cins->mConst.mOperandSize = vr.mType->mSize;
|
||||||
|
block->Append(cins);
|
||||||
|
|
||||||
|
ins->mCode = IC_RETURN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
vr = Dereference(proc, block, vr);
|
vr = Dereference(proc, block, vr);
|
||||||
|
|
||||||
if (!procType->mBase || procType->mBase->mType == DT_TYPE_VOID)
|
if (!procType->mBase || procType->mBase->mType == DT_TYPE_VOID)
|
||||||
|
@ -2201,6 +2313,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
else
|
else
|
||||||
ins->mCode = IC_RETURN_VALUE;
|
ins->mCode = IC_RETURN_VALUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (procType->mBase && procType->mBase->mType != DT_TYPE_VOID)
|
if (procType->mBase && procType->mBase->mType != DT_TYPE_VOID)
|
||||||
|
|
|
@ -729,6 +729,17 @@ Declaration* Parser::ParseDeclaration(bool variable)
|
||||||
|
|
||||||
ndec = ReverseDeclaration(ndec, bdec);
|
ndec = ReverseDeclaration(ndec, bdec);
|
||||||
|
|
||||||
|
// Make room for return value pointer on struct return
|
||||||
|
if (ndec->mBase->mType == DT_TYPE_FUNCTION && ndec->mBase->mBase->mType == DT_TYPE_STRUCT)
|
||||||
|
{
|
||||||
|
Declaration* pdec = ndec->mBase->mParams;
|
||||||
|
while (pdec)
|
||||||
|
{
|
||||||
|
pdec->mVarIndex += 2;
|
||||||
|
pdec = pdec->mNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (definingType)
|
if (definingType)
|
||||||
{
|
{
|
||||||
if (ndec->mIdent)
|
if (ndec->mIdent)
|
||||||
|
|
Loading…
Reference in New Issue