constexpr constructor
This commit is contained in:
parent
d160b2ae65
commit
4e76b34f53
|
@ -621,52 +621,56 @@ Expression* ConstexprInterpreter::EvalConstructor(Expression* exp)
|
||||||
return mResult.ToExpression(mDataSection);
|
return mResult.ToExpression(mDataSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression* ConstexprInterpreter::EvalCall(Expression* exp)
|
Expression* ConstexprInterpreter::EvalTempConstructor(Expression* exp)
|
||||||
{
|
{
|
||||||
mProcType = exp->mLeft->mDecType;
|
Expression* cexp = exp->mLeft->mLeft;
|
||||||
|
|
||||||
Expression* pex = exp->mRight;
|
mProcType = cexp->mLeft->mDecType;
|
||||||
Declaration* dec = exp->mLeft->mDecType->mParams;
|
|
||||||
|
|
||||||
int pos = 0;
|
Expression* pex = cexp->mRight;
|
||||||
if (mProcType->mBase && mProcType->mBase->mType == DT_TYPE_STRUCT)
|
Declaration* dec = cexp->mLeft->mDecType->mParams;
|
||||||
{
|
|
||||||
mResult = Value(exp->mLocation, mProcType->mBase);
|
Value othis = Value(exp->mLocation, exp->mRight->mDecType);
|
||||||
mParams[0] = Value(&mResult);
|
|
||||||
pos = 2;
|
mParams[0] = Value(exp->mLocation, dec->mBase);
|
||||||
}
|
mParams[0].PutPtr(Value(&othis));
|
||||||
|
|
||||||
|
int pos = 2;
|
||||||
|
if (pex->mType == EX_LIST)
|
||||||
|
pex = pex->mRight;
|
||||||
|
else
|
||||||
|
pex = nullptr;
|
||||||
|
dec = dec->mNext;
|
||||||
|
|
||||||
while (pex && pex->mType == EX_LIST)
|
while (pex && pex->mType == EX_LIST)
|
||||||
{
|
{
|
||||||
if (dec)
|
if (!AddParam(pos, pex->mLeft, dec))
|
||||||
pos = dec->mVarIndex;
|
|
||||||
|
|
||||||
if (pex->mLeft->mType == EX_CONSTANT)
|
|
||||||
{
|
|
||||||
if (pex->mLeft->mDecType->mType == DT_TYPE_ARRAY)
|
|
||||||
{
|
|
||||||
Value * tmp = new Value(pex->mLeft);
|
|
||||||
mTemps.Push(tmp);
|
|
||||||
mParams[pos] = Value(pex->mLeft->mLocation, pex->mLeft->mDecType->BuildArrayPointer());
|
|
||||||
mParams[pos].PutPtr(Value(tmp));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mParams[pos] = Value(pex->mLeft);
|
|
||||||
}
|
|
||||||
else if (pex->mLeft->mType == EX_VARIABLE && (pex->mLeft->mDecValue->mFlags & DTF_CONST))
|
|
||||||
{
|
|
||||||
mParams[pos] = Value(pex->mLeft->mLocation, pex->mLeft->mDecValue->mBase);
|
|
||||||
mParams[pos].PutConst(0, pex->mLeft->mDecValue->mValue->mDecValue);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return exp;
|
return exp;
|
||||||
|
|
||||||
pex = pex->mRight;
|
pex = pex->mRight;
|
||||||
if (dec)
|
if (dec)
|
||||||
dec = dec->mNext;
|
dec = dec->mNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pex)
|
if (pex)
|
||||||
{
|
{
|
||||||
|
if (!AddParam(pos, pex, dec))
|
||||||
|
return exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
mHeap = new ExpandingArray<Value*>();
|
||||||
|
|
||||||
|
Execute(cexp->mLeft->mDecValue->mValue);
|
||||||
|
|
||||||
|
if (mHeap->Size() > 0)
|
||||||
|
mErrors->Error(exp->mLocation, EERR_UNBALANCED_HEAP_USE, "Unbalanced heap use in constexpr");
|
||||||
|
delete mHeap;
|
||||||
|
|
||||||
|
return othis.ToExpression(mDataSection);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConstexprInterpreter::AddParam(int& pos, Expression* pex, Declaration* dec)
|
||||||
|
{
|
||||||
if (dec)
|
if (dec)
|
||||||
pos = dec->mVarIndex;
|
pos = dec->mVarIndex;
|
||||||
|
|
||||||
|
@ -689,6 +693,39 @@ Expression* ConstexprInterpreter::EvalCall(Expression* exp)
|
||||||
mParams[pos].PutConst(0, pex->mDecValue->mValue->mDecValue);
|
mParams[pos].PutConst(0, pex->mDecValue->mValue->mDecValue);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression* ConstexprInterpreter::EvalCall(Expression* exp)
|
||||||
|
{
|
||||||
|
mProcType = exp->mLeft->mDecType;
|
||||||
|
|
||||||
|
Expression* pex = exp->mRight;
|
||||||
|
Declaration* dec = exp->mLeft->mDecType->mParams;
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
if (mProcType->mBase && mProcType->mBase->mType == DT_TYPE_STRUCT)
|
||||||
|
{
|
||||||
|
mResult = Value(exp->mLocation, mProcType->mBase);
|
||||||
|
mParams[0] = Value(&mResult);
|
||||||
|
pos = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (pex && pex->mType == EX_LIST)
|
||||||
|
{
|
||||||
|
if (!AddParam(pos, pex->mLeft, dec))
|
||||||
|
return exp;
|
||||||
|
|
||||||
|
pex = pex->mRight;
|
||||||
|
if (dec)
|
||||||
|
dec = dec->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pex)
|
||||||
|
{
|
||||||
|
if (!AddParam(pos, pex, dec))
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,13 @@ public:
|
||||||
ConstexprInterpreter(const Location & loc, Errors * err, LinkerSection * dataSection);
|
ConstexprInterpreter(const Location & loc, Errors * err, LinkerSection * dataSection);
|
||||||
~ConstexprInterpreter(void);
|
~ConstexprInterpreter(void);
|
||||||
|
|
||||||
Expression* EvalCall(Expression* exp);
|
|
||||||
Expression* EvalConstructor(Expression* exp);
|
Expression* EvalConstructor(Expression* exp);
|
||||||
|
Expression* EvalCall(Expression* exp);
|
||||||
|
Expression* EvalTempConstructor(Expression* exp);
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
bool AddParam(int& pos, Expression* pex, Declaration* dec);
|
||||||
|
|
||||||
struct Value;
|
struct Value;
|
||||||
|
|
||||||
struct ValueItem
|
struct ValueItem
|
||||||
|
|
|
@ -900,6 +900,14 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
||||||
ConstexprInterpreter cinter(mLocation, errors, dataSection);
|
ConstexprInterpreter cinter(mLocation, errors, dataSection);
|
||||||
return cinter.EvalCall(this);
|
return cinter.EvalCall(this);
|
||||||
}
|
}
|
||||||
|
else if (mType == EX_CONSTRUCT && mLeft->mType == EX_LIST && !mLeft->mRight && mLeft->mLeft->mType == EX_CALL &&
|
||||||
|
mLeft->mLeft->mLeft->mType == EX_CONSTANT && (mLeft->mLeft->mLeft->mDecValue->mFlags & DTF_CONSTEXPR) &&
|
||||||
|
(mRight->mDecValue->mFlags & DTF_TEMPORARY) &&
|
||||||
|
dataSection)
|
||||||
|
{
|
||||||
|
ConstexprInterpreter cinter(mLocation, errors, dataSection);
|
||||||
|
return cinter.EvalTempConstructor(this);
|
||||||
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1552,6 +1552,7 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression* texp = ParseInitExpression(dtype->mBase);
|
Expression* texp = ParseInitExpression(dtype->mBase);
|
||||||
|
texp = texp->ConstantFold(mErrors, mDataSection);
|
||||||
for (int i = 0; i < nrep; i++)
|
for (int i = 0; i < nrep; i++)
|
||||||
{
|
{
|
||||||
Declaration* cdec = CopyConstantInitializer(index, dtype->mBase, texp);
|
Declaration* cdec = CopyConstantInitializer(index, dtype->mBase, texp);
|
||||||
|
|
Loading…
Reference in New Issue