Complete function struct return
This commit is contained in:
parent
ed52725a01
commit
001e50ae08
|
@ -27,7 +27,6 @@ There are still several open areas, but most targets have been reached. The cur
|
||||||
|
|
||||||
### Language
|
### Language
|
||||||
|
|
||||||
* No struct function return
|
|
||||||
* Missing const checks for structs and enums
|
* Missing const checks for structs and enums
|
||||||
* Missing warnings for all kind of abuses
|
* Missing warnings for all kind of abuses
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,9 @@ if %errorlevel% neq 0 goto :error
|
||||||
call :test funcvartest.c
|
call :test funcvartest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
call :test structassigntest.c
|
||||||
|
if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
exit /b 0
|
exit /b 0
|
||||||
|
|
||||||
:error
|
:error
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
struct Vec3
|
||||||
|
{
|
||||||
|
float x, y, z;
|
||||||
|
};
|
||||||
|
|
||||||
|
Vec3 v;
|
||||||
|
|
||||||
|
Vec3 vadd(Vec3 s1, Vec3 s2)
|
||||||
|
{
|
||||||
|
Vec3 r;
|
||||||
|
r.x = s1.x + s2.x;
|
||||||
|
r.y = s1.y + s2.y;
|
||||||
|
r.z = s1.z + s2.z;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
Vec3 m = {1, 2, -3}, u = {4, 5, -9}, t = {7, -2, -5};
|
||||||
|
|
||||||
|
v.x = 99;
|
||||||
|
v.y = 100;
|
||||||
|
v.z = 101;
|
||||||
|
|
||||||
|
v = vadd(m, vadd(u, t));
|
||||||
|
|
||||||
|
return v.x + v.y + v.z;
|
||||||
|
}
|
|
@ -72,7 +72,7 @@ void GlobalAnalyzer::AutoInline(void)
|
||||||
int cost = (f->mComplexity - 20 * nparams);
|
int cost = (f->mComplexity - 20 * nparams);
|
||||||
|
|
||||||
bool doinline = false;
|
bool doinline = false;
|
||||||
if ((mCompilerOptions & COPT_OPTIMIZE_INLINE) && (f->mFlags & DTF_INLINE))
|
if ((mCompilerOptions & COPT_OPTIMIZE_INLINE) && (f->mFlags & DTF_REQUEST_INLINE))
|
||||||
doinline = true;
|
doinline = true;
|
||||||
if ((mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE) && (cost * (f->mCallers.Size() - 1) <= 0))
|
if ((mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE) && (cost * (f->mCallers.Size() - 1) <= 0))
|
||||||
doinline = true;
|
doinline = true;
|
||||||
|
|
|
@ -962,11 +962,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
{
|
{
|
||||||
InterInstruction* ins = new InterInstruction();
|
InterInstruction* ins = new InterInstruction();
|
||||||
ins->mCode = IC_COPY;
|
ins->mCode = IC_COPY;
|
||||||
ins->mConst.mMemory = IM_INDIRECT;
|
|
||||||
ins->mSrc[0].mType = IT_POINTER;
|
ins->mSrc[0].mType = IT_POINTER;
|
||||||
ins->mSrc[0].mTemp = vr.mTemp;
|
ins->mSrc[0].mTemp = vr.mTemp;
|
||||||
|
ins->mSrc[0].mMemory = IM_INDIRECT;
|
||||||
ins->mSrc[1].mType = IT_POINTER;
|
ins->mSrc[1].mType = IT_POINTER;
|
||||||
ins->mSrc[1].mTemp = vl.mTemp;
|
ins->mSrc[1].mTemp = vl.mTemp;
|
||||||
|
ins->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
ins->mConst.mOperandSize = vl.mType->mSize;
|
ins->mConst.mOperandSize = vl.mType->mSize;
|
||||||
block->Append(ins);
|
block->Append(ins);
|
||||||
}
|
}
|
||||||
|
@ -1819,45 +1820,73 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
pex = nullptr;
|
pex = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
vr = TranslateExpression(procType, proc, block, texp, breakBlock, continueBlock, inlineMapper);
|
ExValue vp(pdec ? pdec->mBase : TheSignedIntTypeDeclaration, ains->mDst.mTemp, 1);
|
||||||
|
|
||||||
if (vr.mType->mType == DT_TYPE_ARRAY || vr.mType->mType == DT_TYPE_FUNCTION)
|
vr = TranslateExpression(procType, proc, block, texp, breakBlock, continueBlock, inlineMapper, &vp);
|
||||||
vr = Dereference(proc, block, vr, 1);
|
|
||||||
else
|
|
||||||
vr = Dereference(proc, block, vr);
|
|
||||||
|
|
||||||
if (pdec)
|
if (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION)
|
||||||
{
|
{
|
||||||
if (!pdec->mBase->CanAssign(vr.mType))
|
if (pdec && !pdec->mBase->CanAssign(vr.mType))
|
||||||
mErrors->Error(texp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types");
|
mErrors->Error(texp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types");
|
||||||
vr = CoerceType(proc, block, vr, pdec->mBase);
|
|
||||||
}
|
|
||||||
else if (vr.mType->IsIntegerType() && vr.mType->mSize < 2)
|
|
||||||
{
|
|
||||||
vr = CoerceType(proc, block, vr, TheSignedIntTypeDeclaration);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
vr = Dereference(proc, block, vr, 1);
|
||||||
|
|
||||||
InterInstruction* wins = new InterInstruction();
|
if (vr.mReference != 1)
|
||||||
wins->mCode = IC_STORE;
|
mErrors->Error(exp->mLeft->mLocation, EERR_NOT_AN_LVALUE, "Not an adressable expression");
|
||||||
wins->mSrc[1].mMemory = IM_INDIRECT;
|
|
||||||
wins->mSrc[0].mType = InterTypeOf(vr.mType);;
|
if (vp.mTemp != vr.mTemp)
|
||||||
wins->mSrc[0].mTemp = vr.mTemp;
|
{
|
||||||
wins->mSrc[1].mType = IT_POINTER;
|
InterInstruction* cins = new InterInstruction();
|
||||||
wins->mSrc[1].mTemp = ains->mDst.mTemp;
|
cins->mCode = IC_COPY;
|
||||||
if (pdec)
|
cins->mSrc[0].mType = IT_POINTER;
|
||||||
{
|
cins->mSrc[0].mTemp = vr.mTemp;
|
||||||
if (pdec->mBase->mType == DT_TYPE_ARRAY)
|
cins->mSrc[0].mMemory = IM_INDIRECT;
|
||||||
wins->mSrc[1].mOperandSize = 2;
|
cins->mSrc[1].mType = IT_POINTER;
|
||||||
else
|
cins->mSrc[1].mTemp = ains->mDst.mTemp;
|
||||||
wins->mSrc[1].mOperandSize = pdec->mSize;
|
cins->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
|
cins->mConst.mOperandSize = vr.mType->mSize;
|
||||||
|
block->Append(cins);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (vr.mType->mSize > 2 && vr.mType->mType != DT_TYPE_ARRAY)
|
|
||||||
wins->mSrc[1].mOperandSize = vr.mType->mSize;
|
|
||||||
else
|
else
|
||||||
wins->mSrc[1].mOperandSize = 2;
|
{
|
||||||
|
if (vr.mType->mType == DT_TYPE_ARRAY || vr.mType->mType == DT_TYPE_FUNCTION)
|
||||||
|
vr = Dereference(proc, block, vr, 1);
|
||||||
|
else
|
||||||
|
vr = Dereference(proc, block, vr);
|
||||||
|
|
||||||
|
if (pdec)
|
||||||
|
{
|
||||||
|
if (!pdec->mBase->CanAssign(vr.mType))
|
||||||
|
mErrors->Error(texp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types");
|
||||||
|
vr = CoerceType(proc, block, vr, pdec->mBase);
|
||||||
|
}
|
||||||
|
else if (vr.mType->IsIntegerType() && vr.mType->mSize < 2)
|
||||||
|
{
|
||||||
|
vr = CoerceType(proc, block, vr, TheSignedIntTypeDeclaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
InterInstruction* wins = new InterInstruction();
|
||||||
|
wins->mCode = IC_STORE;
|
||||||
|
wins->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
|
wins->mSrc[0].mType = InterTypeOf(vr.mType);;
|
||||||
|
wins->mSrc[0].mTemp = vr.mTemp;
|
||||||
|
wins->mSrc[1].mType = IT_POINTER;
|
||||||
|
wins->mSrc[1].mTemp = ains->mDst.mTemp;
|
||||||
|
if (pdec)
|
||||||
|
{
|
||||||
|
if (pdec->mBase->mType == DT_TYPE_ARRAY)
|
||||||
|
wins->mSrc[1].mOperandSize = 2;
|
||||||
|
else
|
||||||
|
wins->mSrc[1].mOperandSize = pdec->mSize;
|
||||||
|
}
|
||||||
|
else if (vr.mType->mSize > 2 && vr.mType->mType != DT_TYPE_ARRAY)
|
||||||
|
wins->mSrc[1].mOperandSize = vr.mType->mSize;
|
||||||
|
else
|
||||||
|
wins->mSrc[1].mOperandSize = 2;
|
||||||
|
block->Append(wins);
|
||||||
|
}
|
||||||
|
|
||||||
block->Append(wins);
|
|
||||||
if (pdec)
|
if (pdec)
|
||||||
pdec = pdec->mNext;
|
pdec = pdec->mNext;
|
||||||
}
|
}
|
||||||
|
@ -2066,11 +2095,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
{
|
{
|
||||||
InterInstruction* cins = new InterInstruction();
|
InterInstruction* cins = new InterInstruction();
|
||||||
cins->mCode = IC_COPY;
|
cins->mCode = IC_COPY;
|
||||||
cins->mConst.mMemory = IM_INDIRECT;
|
|
||||||
cins->mSrc[0].mType = IT_POINTER;
|
cins->mSrc[0].mType = IT_POINTER;
|
||||||
cins->mSrc[0].mTemp = vr.mTemp;
|
cins->mSrc[0].mTemp = vr.mTemp;
|
||||||
|
cins->mSrc[0].mMemory = IM_INDIRECT;
|
||||||
cins->mSrc[1].mType = IT_POINTER;
|
cins->mSrc[1].mType = IT_POINTER;
|
||||||
cins->mSrc[1].mTemp = ains->mDst.mTemp;
|
cins->mSrc[1].mTemp = ains->mDst.mTemp;
|
||||||
|
cins->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
cins->mConst.mOperandSize = vr.mType->mSize;
|
cins->mConst.mOperandSize = vr.mType->mSize;
|
||||||
block->Append(cins);
|
block->Append(cins);
|
||||||
}
|
}
|
||||||
|
@ -2273,38 +2303,56 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
mErrors->Error(exp->mLocation, EERR_INVALID_RETURN, "Non addressable object");
|
mErrors->Error(exp->mLocation, EERR_INVALID_RETURN, "Non addressable object");
|
||||||
|
|
||||||
InterInstruction* ains = new InterInstruction();
|
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();
|
if (inlineMapper)
|
||||||
rins->mCode = IC_LOAD;
|
{
|
||||||
rins->mSrc[0].mMemory = IM_INDIRECT;
|
ains->mCode = IC_CONSTANT;
|
||||||
rins->mSrc[0].mType = IT_POINTER;
|
ains->mDst.mType = IT_POINTER;
|
||||||
rins->mSrc[0].mTemp = ains->mDst.mTemp;
|
ains->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||||
rins->mDst.mType = IT_POINTER;
|
ains->mConst.mOperandSize = procType->mBase->mSize;
|
||||||
rins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
ains->mConst.mIntConst = 0;
|
||||||
block->Append(rins);
|
ains->mConst.mVarIndex = inlineMapper->mResult;
|
||||||
|
ains->mConst.mMemory = IM_LOCAL;
|
||||||
|
block->Append(ains);
|
||||||
|
|
||||||
|
ins->mCode = IC_NONE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InterInstruction* pins = new InterInstruction();
|
||||||
|
pins->mCode = IC_CONSTANT;
|
||||||
|
pins->mDst.mType = IT_POINTER;
|
||||||
|
pins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||||
|
pins->mConst.mVarIndex = 0;
|
||||||
|
pins->mConst.mIntConst = 0;
|
||||||
|
pins->mConst.mOperandSize = 2;
|
||||||
|
if (procType->mFlags & DTF_FASTCALL)
|
||||||
|
pins->mConst.mMemory = IM_FPARAM;
|
||||||
|
else
|
||||||
|
pins->mConst.mMemory = IM_PARAM;
|
||||||
|
block->Append(pins);
|
||||||
|
|
||||||
|
ains->mCode = IC_LOAD;
|
||||||
|
ains->mSrc[0].mMemory = IM_INDIRECT;
|
||||||
|
ains->mSrc[0].mType = IT_POINTER;
|
||||||
|
ains->mSrc[0].mTemp = pins->mDst.mTemp;
|
||||||
|
ains->mDst.mType = IT_POINTER;
|
||||||
|
ains->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||||
|
block->Append(ains);
|
||||||
|
|
||||||
|
ins->mCode = IC_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
InterInstruction* cins = new InterInstruction();
|
InterInstruction* cins = new InterInstruction();
|
||||||
cins->mCode = IC_COPY;
|
cins->mCode = IC_COPY;
|
||||||
cins->mConst.mMemory = IM_INDIRECT;
|
|
||||||
cins->mSrc[0].mType = IT_POINTER;
|
cins->mSrc[0].mType = IT_POINTER;
|
||||||
cins->mSrc[0].mTemp = vr.mTemp;
|
cins->mSrc[0].mTemp = vr.mTemp;
|
||||||
|
cins->mSrc[0].mMemory = IM_INDIRECT;
|
||||||
cins->mSrc[1].mType = IT_POINTER;
|
cins->mSrc[1].mType = IT_POINTER;
|
||||||
cins->mSrc[1].mTemp = rins->mDst.mTemp;
|
cins->mSrc[1].mTemp = ains->mDst.mTemp;
|
||||||
|
cins->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
cins->mConst.mOperandSize = vr.mType->mSize;
|
cins->mConst.mOperandSize = vr.mType->mSize;
|
||||||
block->Append(cins);
|
block->Append(cins);
|
||||||
|
|
||||||
ins->mCode = IC_RETURN;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue