Fix pointers in constexpr
This commit is contained in:
parent
e20c098ab1
commit
a0409002b6
|
@ -18,6 +18,9 @@ rem @echo off
|
||||||
@call :test opp_streamtest.cpp
|
@call :test opp_streamtest.cpp
|
||||||
@if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
@call :test opp_pairtest.cpp
|
||||||
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
@call :test operatoroverload.cpp
|
@call :test operatoroverload.cpp
|
||||||
@if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
#include <assert.h>
|
||||||
|
#include <opp/vector.h>
|
||||||
|
#include <opp/utility.h>
|
||||||
|
#include <opp/iostream.h>
|
||||||
|
|
||||||
|
using namespace opp;
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
vector<pair<int, int> > vii;
|
||||||
|
|
||||||
|
for(int i=0; i<100; i++)
|
||||||
|
vii.push_back(make_pair(i, i * i));
|
||||||
|
|
||||||
|
int sum1 = 0;
|
||||||
|
long sum2 = 0;
|
||||||
|
for(const auto & v : vii)
|
||||||
|
{
|
||||||
|
sum1 += v.first;
|
||||||
|
sum2 += v.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
assert(sum1 == 4950);
|
||||||
|
assert(sum2 == 328350l);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,14 +0,0 @@
|
||||||
#ifndef OPP_MOVE_H
|
|
||||||
#define OPP_MOVE_H
|
|
||||||
|
|
||||||
namespace opp {
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
T && move(T & m)
|
|
||||||
{
|
|
||||||
return (T &&)m;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef OPP_UTILITY_H
|
||||||
|
#define OPP_UTILITY_H
|
||||||
|
|
||||||
|
namespace opp {
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T && move(T & m)
|
||||||
|
{
|
||||||
|
return (T &&)m;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T1, class T2>
|
||||||
|
struct pair
|
||||||
|
{
|
||||||
|
T1 first;
|
||||||
|
T2 second;
|
||||||
|
|
||||||
|
pair(T1 && t1, T2 && t2)
|
||||||
|
: first(t1), second(t2)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T1, class T2>
|
||||||
|
constexpr pair<T1, T2> make_pair(T1 && t1, T2 && t2)
|
||||||
|
{
|
||||||
|
return pair<T1, T2>(t1, t2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -2,7 +2,7 @@
|
||||||
#define OPP_VECTOR_H
|
#define OPP_VECTOR_H
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <opp/move.h>
|
#include <opp/utility.h>
|
||||||
|
|
||||||
namespace opp {
|
namespace opp {
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ void ConstexprInterpreter::Value::PutConst(int offset, Declaration* dec)
|
||||||
switch (dec->mType)
|
switch (dec->mType)
|
||||||
{
|
{
|
||||||
case DT_CONST_INTEGER:
|
case DT_CONST_INTEGER:
|
||||||
|
case DT_CONST_ADDRESS:
|
||||||
PutIntAt(dec->mInteger, offset, dec->mBase);
|
PutIntAt(dec->mInteger, offset, dec->mBase);
|
||||||
break;
|
break;
|
||||||
case DT_CONST_FLOAT:
|
case DT_CONST_FLOAT:
|
||||||
|
@ -46,6 +47,10 @@ void ConstexprInterpreter::Value::PutConst(int offset, Declaration* dec)
|
||||||
for (Declaration* pdec = dec->mParams; pdec; pdec = pdec->mNext)
|
for (Declaration* pdec = dec->mParams; pdec; pdec = pdec->mNext)
|
||||||
PutConst(pdec->mOffset, pdec);
|
PutConst(pdec->mOffset, pdec);
|
||||||
break;
|
break;
|
||||||
|
case DT_CONST_DATA:
|
||||||
|
for (int i = 0; i < dec->mBase->mSize; i++)
|
||||||
|
PutIntAt(dec->mData[i], offset + i, TheConstCharTypeDeclaration);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,8 +121,8 @@ ConstexprInterpreter::Value::Value(Value* value)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstexprInterpreter::Value::Value(Value* value, Declaration* type, int offset)
|
ConstexprInterpreter::Value::Value(const Location& location, Value* value, Declaration* type, int offset)
|
||||||
: mLocation(value->mLocation),
|
: mLocation(location),
|
||||||
mDecType(type),
|
mDecType(type),
|
||||||
mBaseValue(value), mOffset(offset),
|
mBaseValue(value), mOffset(offset),
|
||||||
mDataSize(0), mData(mShortData)
|
mDataSize(0), mData(mShortData)
|
||||||
|
@ -331,7 +336,7 @@ ConstexprInterpreter::Value ConstexprInterpreter::Value::GetPtrAt(int at, Declar
|
||||||
{
|
{
|
||||||
const ValueItem* dp = GetAddr() + at;
|
const ValueItem* dp = GetAddr() + at;
|
||||||
|
|
||||||
return Value(dp->mBaseValue, type, uint16(dp[0].mByte | ((uint32)(dp[1].mByte) << 8)));
|
return Value(mLocation, dp->mBaseValue, type, uint16(dp[0].mByte | ((uint32)(dp[1].mByte) << 8)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConstexprInterpreter::Value::PutIntAt(int64 v, int at, Declaration* type)
|
void ConstexprInterpreter::Value::PutIntAt(int64 v, int at, Declaration* type)
|
||||||
|
@ -448,19 +453,27 @@ Declaration* ConstexprInterpreter::Value::GetConst(int offset, Declaration* type
|
||||||
dec->mSize = type->mSize;
|
dec->mSize = type->mSize;
|
||||||
dec->mSection = dataSection;
|
dec->mSection = dataSection;
|
||||||
dec->mOffset = offset;
|
dec->mOffset = offset;
|
||||||
|
|
||||||
Declaration* ldec = nullptr;
|
Declaration* ldec = nullptr;
|
||||||
for (Declaration* mdec = type->mParams; mdec; mdec = mdec->mNext)
|
while (type)
|
||||||
{
|
{
|
||||||
Declaration * cdec = GetConst(offset + mdec->mOffset, mdec->mBase, dataSection);
|
for (Declaration* mdec = type->mParams; mdec; mdec = mdec->mNext)
|
||||||
cdec->mOffset = mdec->mOffset;
|
{
|
||||||
|
Declaration* cdec = GetConst(offset + mdec->mOffset, mdec->mBase, dataSection);
|
||||||
|
cdec->mOffset = mdec->mOffset;
|
||||||
|
|
||||||
if (ldec)
|
if (ldec)
|
||||||
ldec->mNext = cdec;
|
ldec->mNext = cdec;
|
||||||
|
else
|
||||||
|
dec->mParams = cdec;
|
||||||
|
|
||||||
|
ldec = cdec;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type->mBase)
|
||||||
|
type = type->mBase->mBase;
|
||||||
else
|
else
|
||||||
dec->mParams = cdec;
|
type = nullptr;
|
||||||
|
|
||||||
ldec = cdec;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -486,6 +499,46 @@ Declaration* ConstexprInterpreter::Value::GetConst(int offset, Declaration* type
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DT_TYPE_POINTER:
|
||||||
|
{
|
||||||
|
Value vp = GetPtrAt(offset, type);
|
||||||
|
if (vp.mBaseValue)
|
||||||
|
{
|
||||||
|
dec = new Declaration(mLocation, DT_CONST_POINTER);
|
||||||
|
dec->mBase = type;
|
||||||
|
dec->mSize = type->mSize;
|
||||||
|
|
||||||
|
Declaration* target;
|
||||||
|
|
||||||
|
if (vp.mBaseValue->mDecType->mType == DT_TYPE_ARRAY)
|
||||||
|
{
|
||||||
|
target = new Declaration(mLocation, DT_CONST_DATA);
|
||||||
|
target->mSize = vp.mBaseValue->mDataSize;
|
||||||
|
target->mBase = vp.mBaseValue->mDecType;
|
||||||
|
target->mSection = dataSection;
|
||||||
|
|
||||||
|
uint8* buffer = new uint8[target->mSize];
|
||||||
|
for (int i = 0; i < target->mSize; i++)
|
||||||
|
buffer[i] = uint8(vp.mBaseValue->GetIntAt(i, TheUnsignedCharTypeDeclaration));
|
||||||
|
target->mData = buffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
target = vp.mBaseValue->GetConst(0, vp.mBaseValue->mDecType, dataSection);
|
||||||
|
|
||||||
|
dec->mValue = new Expression(mLocation, EX_CONSTANT);
|
||||||
|
dec->mValue->mDecType = target->mBase;
|
||||||
|
dec->mValue->mDecValue = target;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dec = new Declaration(mLocation, DT_CONST_ADDRESS);
|
||||||
|
dec->mBase = type;
|
||||||
|
dec->mFlags = 0;
|
||||||
|
dec->mSize = type->mSize;
|
||||||
|
dec->mInteger = vp.mOffset;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,7 +564,8 @@ ConstexprInterpreter::ConstexprInterpreter(const Location & location, Errors* er
|
||||||
|
|
||||||
ConstexprInterpreter::~ConstexprInterpreter(void)
|
ConstexprInterpreter::~ConstexprInterpreter(void)
|
||||||
{
|
{
|
||||||
|
for (int i = 0; i < mTemps.Size(); i++)
|
||||||
|
delete mTemps[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstexprInterpreter::Value* ConstexprInterpreter::NewValue(Expression* exp, Declaration* type, int size)
|
ConstexprInterpreter::Value* ConstexprInterpreter::NewValue(Expression* exp, Declaration* type, int size)
|
||||||
|
@ -541,13 +595,30 @@ Expression* ConstexprInterpreter::EvalCall(Expression* exp)
|
||||||
Declaration* dec = exp->mLeft->mDecType->mParams;
|
Declaration* dec = exp->mLeft->mDecType->mParams;
|
||||||
|
|
||||||
int pos = 0;
|
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)
|
while (pex && pex->mType == EX_LIST)
|
||||||
{
|
{
|
||||||
if (dec)
|
if (dec)
|
||||||
pos = dec->mVarIndex;
|
pos = dec->mVarIndex;
|
||||||
|
|
||||||
if (pex->mLeft->mType == EX_CONSTANT)
|
if (pex->mLeft->mType == EX_CONSTANT)
|
||||||
mParams[pos] = Value(pex->mLeft);
|
{
|
||||||
|
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))
|
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] = Value(pex->mLeft->mLocation, pex->mLeft->mDecValue->mBase);
|
||||||
|
@ -566,7 +637,17 @@ Expression* ConstexprInterpreter::EvalCall(Expression* exp)
|
||||||
pos = dec->mVarIndex;
|
pos = dec->mVarIndex;
|
||||||
|
|
||||||
if (pex->mType == EX_CONSTANT)
|
if (pex->mType == EX_CONSTANT)
|
||||||
mParams[pos] = Value(pex);
|
{
|
||||||
|
if (pex->mDecType->mType == DT_TYPE_ARRAY)
|
||||||
|
{
|
||||||
|
Value* tmp = new Value(pex);
|
||||||
|
mTemps.Push(tmp);
|
||||||
|
mParams[pos] = Value(pex->mLocation, pex->mDecType->BuildArrayPointer());
|
||||||
|
mParams[pos].PutPtr(Value(tmp));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mParams[pos] = Value(pex);
|
||||||
|
}
|
||||||
else if (pex->mType == EX_VARIABLE && (pex->mDecValue->mFlags & DTF_CONST))
|
else if (pex->mType == EX_VARIABLE && (pex->mDecValue->mFlags & DTF_CONST))
|
||||||
{
|
{
|
||||||
mParams[pos] = Value(pex->mLocation, pex->mDecValue->mBase);
|
mParams[pos] = Value(pex->mLocation, pex->mDecValue->mBase);
|
||||||
|
@ -619,6 +700,12 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalBinary(Expression * exp, c
|
||||||
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible operator", TokenNames[exp->mToken]);
|
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible operator", TokenNames[exp->mToken]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (exp->mDecType->mType == DT_TYPE_POINTER)
|
||||||
|
{
|
||||||
|
Value vlp = vl.GetPtr();
|
||||||
|
vlp.mOffset += int(vr.GetInt() * vl.mDecType->mBase->mSize);
|
||||||
|
v.PutPtr(vlp);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (exp->mToken)
|
switch (exp->mToken)
|
||||||
|
@ -880,6 +967,13 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalCall(Expression* exp, Cons
|
||||||
Declaration* dec = exp->mLeft->mDecType->mParams;
|
Declaration* dec = exp->mLeft->mDecType->mParams;
|
||||||
|
|
||||||
int pos = 0;
|
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)
|
while (pex && pex->mType == EX_LIST)
|
||||||
{
|
{
|
||||||
if (dec)
|
if (dec)
|
||||||
|
@ -1096,7 +1190,7 @@ ConstexprInterpreter::Value ConstexprInterpreter::Eval(Expression* exp)
|
||||||
{
|
{
|
||||||
Value v = Eval(exp->mLeft);
|
Value v = Eval(exp->mLeft);
|
||||||
if (v.mBaseValue)
|
if (v.mBaseValue)
|
||||||
return Value(v.mBaseValue, exp->mDecType, v.mOffset + exp->mDecValue->mOffset);
|
return Value(exp->mLocation, v.mBaseValue, exp->mDecType, v.mOffset + exp->mDecValue->mOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
case EX_INDEX:
|
case EX_INDEX:
|
||||||
|
@ -1107,15 +1201,26 @@ ConstexprInterpreter::Value ConstexprInterpreter::Eval(Expression* exp)
|
||||||
if (v.mDecType->mType == DT_TYPE_ARRAY)
|
if (v.mDecType->mType == DT_TYPE_ARRAY)
|
||||||
{
|
{
|
||||||
if (v.mBaseValue)
|
if (v.mBaseValue)
|
||||||
return Value(v.mBaseValue, exp->mDecType, v.mOffset + v.mDecType->mBase->mSize * int(vi.GetInt()));
|
return Value(exp->mLocation, v.mBaseValue, exp->mDecType, v.mOffset + v.mDecType->mBase->mSize * int(vi.GetInt()));
|
||||||
}
|
}
|
||||||
else if (v.mDecType->mType == DT_TYPE_POINTER)
|
else if (v.mDecType->mType == DT_TYPE_POINTER)
|
||||||
{
|
{
|
||||||
Value p = v.GetPtr();
|
Value p = v.GetPtr();
|
||||||
return Value(p.mBaseValue, exp->mDecType, p.mOffset + v.mDecType->mBase->mSize * int(vi.GetInt()));
|
return Value(exp->mLocation, p.mBaseValue, exp->mDecType, p.mOffset + v.mDecType->mBase->mSize * int(vi.GetInt()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case EX_RESULT:
|
||||||
|
if (mParams[0].mBaseValue)
|
||||||
|
return mParams[0];
|
||||||
|
else
|
||||||
|
return Value(&mParams[0]);
|
||||||
|
|
||||||
|
case EX_CONSTRUCT:
|
||||||
|
if (exp->mLeft->mLeft)
|
||||||
|
Eval(exp->mLeft->mLeft);
|
||||||
|
return Eval(exp->mRight);
|
||||||
|
|
||||||
case EX_VOID:
|
case EX_VOID:
|
||||||
return Value(exp->mLocation);
|
return Value(exp->mLocation);
|
||||||
|
|
||||||
|
@ -1162,6 +1267,7 @@ ConstexprInterpreter::Flow ConstexprInterpreter::Execute(Expression* exp)
|
||||||
case EX_PREINCDEC:
|
case EX_PREINCDEC:
|
||||||
case EX_QUALIFY:
|
case EX_QUALIFY:
|
||||||
case EX_INDEX:
|
case EX_INDEX:
|
||||||
|
case EX_RESULT:
|
||||||
Eval(exp);
|
Eval(exp);
|
||||||
return FLOW_NEXT;
|
return FLOW_NEXT;
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ protected:
|
||||||
Value(const Location& location, Declaration* dec, int count);
|
Value(const Location& location, Declaration* dec, int count);
|
||||||
Value(const Value& value);
|
Value(const Value& value);
|
||||||
Value(Value&& value);
|
Value(Value&& value);
|
||||||
Value(Value * value, Declaration * type, int offset);
|
Value(const Location& location, Value * value, Declaration * type, int offset);
|
||||||
Value(Value* value);
|
Value(Value* value);
|
||||||
Value(const Location& location, const uint8 * data, Declaration* type);
|
Value(const Location& location, const uint8 * data, Declaration* type);
|
||||||
Value(const Location& location, const ValueItem* data, Declaration* type);
|
Value(const Location& location, const ValueItem* data, Declaration* type);
|
||||||
|
@ -101,6 +101,7 @@ protected:
|
||||||
GrowingArray<Value> mParams, mLocals;
|
GrowingArray<Value> mParams, mLocals;
|
||||||
ExpandingArray<Expression*> mDestructStack;
|
ExpandingArray<Expression*> mDestructStack;
|
||||||
ExpandingArray<Value *> * mHeap;
|
ExpandingArray<Value *> * mHeap;
|
||||||
|
ExpandingArray<Value*> mTemps;
|
||||||
|
|
||||||
Errors * mErrors;
|
Errors * mErrors;
|
||||||
Value mResult;
|
Value mResult;
|
||||||
|
|
|
@ -303,6 +303,9 @@ void Expression::Dump(int ident) const
|
||||||
case EX_PACK:
|
case EX_PACK:
|
||||||
printf("PACK");
|
printf("PACK");
|
||||||
break;
|
break;
|
||||||
|
case EX_PACK_TYPE:
|
||||||
|
printf("PACK_TYPE");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
@ -355,6 +358,16 @@ bool Expression::IsRValue(void) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Expression::IsConstRef(void) const
|
||||||
|
{
|
||||||
|
if (mDecType->mType == DT_TYPE_RVALUEREF || mDecType->mType == DT_TYPE_REFERENCE)
|
||||||
|
return true;
|
||||||
|
else if (mType == EX_VARIABLE || mType == EX_QUALIFY || mType == EX_INDEX || mType == EX_PREFIX && mToken == TK_MUL)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Expression::IsLValue(void) const
|
bool Expression::IsLValue(void) const
|
||||||
{
|
{
|
||||||
if (mDecType->mFlags & DTF_CONST)
|
if (mDecType->mFlags & DTF_CONST)
|
||||||
|
@ -996,7 +1009,7 @@ Declaration* Declaration::DeduceAuto(Declaration * dec)
|
||||||
if (dec->mType == DT_TYPE_ARRAY)
|
if (dec->mType == DT_TYPE_ARRAY)
|
||||||
dec = dec->mBase->BuildPointer(mLocation);
|
dec = dec->mBase->BuildPointer(mLocation);
|
||||||
|
|
||||||
if (mFlags & DTF_CONST)
|
if ((IsReference() ? mBase->mFlags : mFlags) & DTF_CONST)
|
||||||
dec = dec->ToConstType();
|
dec = dec->ToConstType();
|
||||||
else
|
else
|
||||||
dec = dec->ToMutableType();
|
dec = dec->ToMutableType();
|
||||||
|
@ -1133,7 +1146,7 @@ const Ident* Declaration::MangleIdent(void)
|
||||||
}
|
}
|
||||||
else if (mType == DT_PACK_TYPE)
|
else if (mType == DT_PACK_TYPE)
|
||||||
{
|
{
|
||||||
Declaration* dec = mBase;
|
Declaration* dec = mParams;
|
||||||
while (dec)
|
while (dec)
|
||||||
{
|
{
|
||||||
const Ident* id = dec->MangleIdent();
|
const Ident* id = dec->MangleIdent();
|
||||||
|
@ -1288,7 +1301,7 @@ bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec)
|
||||||
tpdec->mIdent = pdec->mBase->mBase->mIdent;
|
tpdec->mIdent = pdec->mBase->mBase->mIdent;
|
||||||
else
|
else
|
||||||
tpdec->mIdent = pdec->mBase->mIdent;
|
tpdec->mIdent = pdec->mBase->mIdent;
|
||||||
tpdec->mBase = phead;
|
tpdec->mParams = phead;
|
||||||
mScope->Insert(tpdec->mIdent, tpdec);
|
mScope->Insert(tpdec->mIdent, tpdec);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1434,25 +1447,66 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
|
||||||
Declaration *ftdec = tdec->mTemplate;
|
Declaration *ftdec = tdec->mTemplate;
|
||||||
while (ftdec)
|
while (ftdec)
|
||||||
{
|
{
|
||||||
if (ftdec->mBase->IsConstSame(fdec))
|
if (ftdec->mBase->mQualIdent == fdec->mQualIdent)
|
||||||
{
|
{
|
||||||
Declaration* fpdec = ftdec->mParams;
|
Declaration* fpdec = ftdec->mParams;
|
||||||
Declaration* tpdec = tdec->mTemplate->mParams;
|
Declaration* tpdec = tdec->mTemplate->mParams;
|
||||||
|
|
||||||
while (fpdec)
|
while (fpdec && tpdec)
|
||||||
{
|
{
|
||||||
if (tpdec->mBase->mType == DT_TYPE_TEMPLATE || tpdec->mBase->mType == DT_CONST_TEMPLATE)
|
if (tpdec->mBase->mType == DT_TYPE_TEMPLATE || tpdec->mBase->mType == DT_CONST_TEMPLATE)
|
||||||
{
|
{
|
||||||
Declaration * pdec = mScope->Insert(tpdec->mIdent, fpdec->mBase);
|
Declaration * pdec = mScope->Insert(tpdec->mBase->mIdent, fpdec->mBase);
|
||||||
if (pdec && !pdec->IsSame(fpdec->mBase))
|
if (pdec && !pdec->IsSame(fpdec->mBase))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if (tpdec->mBase->mType == DT_PACK_TEMPLATE)
|
||||||
|
{
|
||||||
|
Declaration* tppack;
|
||||||
|
if (fpdec->mType == DT_PACK_TEMPLATE)
|
||||||
|
tppack = fpdec->mBase;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tppack = new Declaration(fpdec->mLocation, DT_PACK_TYPE);
|
||||||
|
|
||||||
|
Declaration* ppdec = nullptr;
|
||||||
|
|
||||||
|
while (fpdec)
|
||||||
|
{
|
||||||
|
if (fpdec->mType == DT_PACK_TEMPLATE)
|
||||||
|
{
|
||||||
|
if (ppdec)
|
||||||
|
ppdec->mNext = fpdec->mBase->mParams;
|
||||||
|
else
|
||||||
|
tppack->mParams = fpdec->mBase->mParams;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Declaration* ndec = fpdec->mBase->Clone();
|
||||||
|
|
||||||
|
if (ppdec)
|
||||||
|
ppdec->mNext = ndec;
|
||||||
|
else
|
||||||
|
tppack->mParams = ndec;
|
||||||
|
ppdec = ndec;
|
||||||
|
|
||||||
|
fpdec = fpdec->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Declaration* pdec = mScope->Insert(tpdec->mBase->mIdent, tppack);
|
||||||
|
if (pdec && !pdec->IsSame(fpdec->mBase))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
fpdec = fpdec->mNext;
|
fpdec = fpdec->mNext;
|
||||||
tpdec = tpdec->mNext;
|
tpdec = tpdec->mNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return !fpdec && !tpdec;
|
||||||
}
|
}
|
||||||
|
|
||||||
ftdec = ftdec->mNext;
|
ftdec = ftdec->mNext;
|
||||||
|
@ -1604,6 +1658,7 @@ Declaration* Declaration::ToConstType(void)
|
||||||
ndec->mQualIdent = mQualIdent;
|
ndec->mQualIdent = mQualIdent;
|
||||||
ndec->mTemplate = mTemplate;
|
ndec->mTemplate = mTemplate;
|
||||||
|
|
||||||
|
ndec->mDestructor = mDestructor;
|
||||||
ndec->mDefaultConstructor = mDefaultConstructor;
|
ndec->mDefaultConstructor = mDefaultConstructor;
|
||||||
ndec->mCopyConstructor = mCopyConstructor;
|
ndec->mCopyConstructor = mCopyConstructor;
|
||||||
ndec->mMoveConstructor = mMoveConstructor;
|
ndec->mMoveConstructor = mMoveConstructor;
|
||||||
|
@ -1636,6 +1691,7 @@ Declaration* Declaration::ToMutableType(void)
|
||||||
ndec->mQualIdent = mQualIdent;
|
ndec->mQualIdent = mQualIdent;
|
||||||
ndec->mTemplate = mTemplate;
|
ndec->mTemplate = mTemplate;
|
||||||
|
|
||||||
|
ndec->mDestructor = mDestructor;
|
||||||
ndec->mDefaultConstructor = mDefaultConstructor;
|
ndec->mDefaultConstructor = mDefaultConstructor;
|
||||||
ndec->mCopyConstructor = mCopyConstructor;
|
ndec->mCopyConstructor = mCopyConstructor;
|
||||||
ndec->mMoveConstructor = mMoveConstructor;
|
ndec->mMoveConstructor = mMoveConstructor;
|
||||||
|
@ -1659,6 +1715,8 @@ bool Declaration::IsSameTemplate(const Declaration* dec) const
|
||||||
|
|
||||||
if (mType == DT_CONST_FUNCTION)
|
if (mType == DT_CONST_FUNCTION)
|
||||||
return mBase->IsSame(dec->mBase);
|
return mBase->IsSame(dec->mBase);
|
||||||
|
else if (mType == DT_TYPE_STRUCT)
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1673,7 +1731,7 @@ bool Declaration::IsSubType(const Declaration* dec) const
|
||||||
|
|
||||||
if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
|
if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
|
||||||
{
|
{
|
||||||
if (dec->mType == DT_TYPE_POINTER)
|
if (dec->mType == DT_TYPE_POINTER || dec->mType == DT_TYPE_ARRAY)
|
||||||
return /*this->Stride() == dec->Stride() &&*/ mBase->IsSubType(dec->mBase);
|
return /*this->Stride() == dec->Stride() &&*/ mBase->IsSubType(dec->mBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1906,7 +1964,7 @@ bool Declaration::IsSameParams(const Declaration* dec) const
|
||||||
}
|
}
|
||||||
else if (mType == DT_PACK_TYPE && dec->mType == DT_PACK_TYPE)
|
else if (mType == DT_PACK_TYPE && dec->mType == DT_PACK_TYPE)
|
||||||
{
|
{
|
||||||
Declaration* ld = mBase, * rd = dec->mBase;
|
Declaration* ld = mParams, * rd = dec->mParams;
|
||||||
while (ld && rd)
|
while (ld && rd)
|
||||||
{
|
{
|
||||||
if (!ld->IsSame(rd))
|
if (!ld->IsSame(rd))
|
||||||
|
|
|
@ -222,7 +222,8 @@ enum ExpressionType
|
||||||
EX_CONSTRUCT,
|
EX_CONSTRUCT,
|
||||||
EX_CLEANUP,
|
EX_CLEANUP,
|
||||||
EX_RESULT,
|
EX_RESULT,
|
||||||
EX_PACK
|
EX_PACK,
|
||||||
|
EX_PACK_TYPE,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Expression
|
class Expression
|
||||||
|
@ -247,6 +248,7 @@ public:
|
||||||
bool IsSame(const Expression* exp) const;
|
bool IsSame(const Expression* exp) const;
|
||||||
bool IsRValue(void) const;
|
bool IsRValue(void) const;
|
||||||
bool IsLValue(void) const;
|
bool IsLValue(void) const;
|
||||||
|
bool IsConstRef(void) const;
|
||||||
|
|
||||||
void Dump(int ident) const;
|
void Dump(int ident) const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -557,7 +557,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec)
|
||||||
while (pdec)
|
while (pdec)
|
||||||
{
|
{
|
||||||
pdec->mVarIndex += vi;
|
pdec->mVarIndex += vi;
|
||||||
if (pdec->mBase->mType == DT_TYPE_REFERENCE && pdec->mBase->mBase->IsSimpleType() && !(pdec->mBase->mFlags & DTF_VAR_ADDRESS) && (pdec->mBase->mBase->mFlags & DTF_CONST))
|
if (pdec->mBase->mType == DT_TYPE_REFERENCE && pdec->mBase->mBase->IsSimpleType() && !(pdec->mFlags & DTF_VAR_ADDRESS) && (pdec->mBase->mBase->mFlags & DTF_CONST))
|
||||||
{
|
{
|
||||||
pdec->mBase = pdec->mBase->mBase;
|
pdec->mBase = pdec->mBase->mBase;
|
||||||
pdec->mSize = pdec->mBase->mSize;
|
pdec->mSize = pdec->mBase->mSize;
|
||||||
|
@ -884,6 +884,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
||||||
if (pex->mType == EX_CALL && IsStackParam(pex->mDecType) && !(pdec && (pdec->mBase->mType == DT_TYPE_REFERENCE || pdec->mBase->mType == DT_TYPE_RVALUEREF)))
|
if (pex->mType == EX_CALL && IsStackParam(pex->mDecType) && !(pdec && (pdec->mBase->mType == DT_TYPE_REFERENCE || pdec->mBase->mType == DT_TYPE_RVALUEREF)))
|
||||||
ldec->mBase->mFlags |= DTF_STACKCALL;
|
ldec->mBase->mFlags |= DTF_STACKCALL;
|
||||||
|
|
||||||
|
RegisterProc(Analyze(pex, procDec, pdec && pdec->mBase->IsReference()));
|
||||||
|
|
||||||
if (pdec)
|
if (pdec)
|
||||||
pdec = pdec->mNext;
|
pdec = pdec->mNext;
|
||||||
|
|
||||||
|
@ -892,7 +894,6 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
||||||
else
|
else
|
||||||
rex = nullptr;
|
rex = nullptr;
|
||||||
}
|
}
|
||||||
RegisterProc(Analyze(exp->mRight, procDec, false));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EX_LIST:
|
case EX_LIST:
|
||||||
|
@ -901,7 +902,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
||||||
case EX_RETURN:
|
case EX_RETURN:
|
||||||
if (exp->mLeft)
|
if (exp->mLeft)
|
||||||
{
|
{
|
||||||
RegisterProc(Analyze(exp->mLeft, procDec, false));
|
RegisterProc(Analyze(exp->mLeft, procDec, procDec->mBase->mBase->IsReference()));
|
||||||
if (procDec->mBase->mBase && procDec->mBase->mBase->mType == DT_TYPE_STRUCT && procDec->mBase->mBase->mCopyConstructor)
|
if (procDec->mBase->mBase && procDec->mBase->mBase->mType == DT_TYPE_STRUCT && procDec->mBase->mBase->mCopyConstructor)
|
||||||
{
|
{
|
||||||
if (procDec->mBase->mBase->mMoveConstructor)
|
if (procDec->mBase->mBase->mMoveConstructor)
|
||||||
|
@ -1031,8 +1032,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
||||||
procDec->mComplexity += exp->mDecType->mSize * 10;
|
procDec->mComplexity += exp->mDecType->mSize * 10;
|
||||||
|
|
||||||
ldec = Analyze(exp->mLeft, procDec, false);
|
ldec = Analyze(exp->mLeft, procDec, false);
|
||||||
RegisterProc(Analyze(exp->mRight->mLeft, procDec, false));
|
RegisterProc(Analyze(exp->mRight->mLeft, procDec, lhs));
|
||||||
RegisterProc(Analyze(exp->mRight->mRight, procDec, false));
|
RegisterProc(Analyze(exp->mRight->mRight, procDec, lhs));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3679,6 +3679,34 @@ bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (mCode == IC_SELECT)
|
||||||
|
{
|
||||||
|
if (mDst.mType == IT_POINTER)
|
||||||
|
{
|
||||||
|
if (mSrc[1].mTemp < 0)
|
||||||
|
{
|
||||||
|
if (mSrc[1].mMemory == IM_LOCAL)
|
||||||
|
{
|
||||||
|
requiredVars += mSrc[1].mVarIndex;
|
||||||
|
}
|
||||||
|
else if (mSrc[1].mMemory == paramMemory)
|
||||||
|
{
|
||||||
|
requiredParams += mSrc[1].mVarIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mSrc[2].mTemp < 0)
|
||||||
|
{
|
||||||
|
if (mSrc[2].mMemory == IM_LOCAL)
|
||||||
|
{
|
||||||
|
requiredVars += mSrc[2].mVarIndex;
|
||||||
|
}
|
||||||
|
else if (mSrc[2].mMemory == paramMemory)
|
||||||
|
{
|
||||||
|
requiredParams += mSrc[2].mVarIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (mCode == IC_CONSTANT)
|
else if (mCode == IC_CONSTANT)
|
||||||
{
|
{
|
||||||
if (mConst.mType == IT_POINTER)
|
if (mConst.mType == IT_POINTER)
|
||||||
|
@ -3809,6 +3837,22 @@ bool InterInstruction::RemoveUnusedStaticStoreInstructions(InterCodeBasicBlock*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (mCode == IC_SELECT)
|
||||||
|
{
|
||||||
|
if (mDst.mType == IT_POINTER)
|
||||||
|
{
|
||||||
|
if (mSrc[1].mTemp < 0)
|
||||||
|
{
|
||||||
|
if (mSrc[1].mMemory == IM_GLOBAL && mSrc[1].mVarIndex >= 0)
|
||||||
|
requiredVars += mSrc[1].mVarIndex;
|
||||||
|
}
|
||||||
|
if (mSrc[2].mTemp < 0)
|
||||||
|
{
|
||||||
|
if (mSrc[2].mMemory == IM_GLOBAL && mSrc[2].mVarIndex >= 0)
|
||||||
|
requiredVars += mSrc[2].mVarIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (mCode == IC_COPY || mCode == IC_STRCPY)
|
else if (mCode == IC_COPY || mCode == IC_STRCPY)
|
||||||
{
|
{
|
||||||
requiredVars.Fill();
|
requiredVars.Fill();
|
||||||
|
@ -5241,12 +5285,11 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IC_SELECT:
|
case IC_SELECT:
|
||||||
for(int i=0; i<3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
if (ins->mSrc[i].mTemp >= 0 && tvalue[ins->mSrc[i].mTemp] && tvalue[ins->mSrc[i].mTemp]->mCode == IC_CONSTANT)
|
if (ins->mSrc[i].mTemp >= 0 && tvalue[ins->mSrc[i].mTemp] && tvalue[ins->mSrc[i].mTemp]->mCode == IC_CONSTANT && ins->mSrc[i].mType != IT_POINTER)
|
||||||
{
|
{
|
||||||
ins->mSrc[i] = tvalue[ins->mSrc[i].mTemp]->mConst;
|
ins->mSrc[i] = tvalue[ins->mSrc[i].mTemp]->mConst;
|
||||||
ins->mSrc[i].mType = ins->mDst.mType;
|
|
||||||
ins->mSrc[i].mTemp = -1;
|
ins->mSrc[i].mTemp = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16376,6 +16419,8 @@ void InterCodeProcedure::ResetVisited(void)
|
||||||
|
|
||||||
int InterCodeProcedure::AddTemporary(InterType type)
|
int InterCodeProcedure::AddTemporary(InterType type)
|
||||||
{
|
{
|
||||||
|
assert(type != IT_NONE);
|
||||||
|
|
||||||
int temp = mTemporaries.Size();
|
int temp = mTemporaries.Size();
|
||||||
mTemporaries.Push(type);
|
mTemporaries.Push(type);
|
||||||
return temp;
|
return temp;
|
||||||
|
@ -17179,7 +17224,7 @@ void InterCodeProcedure::Close(void)
|
||||||
{
|
{
|
||||||
GrowingTypeArray tstack(IT_NONE);
|
GrowingTypeArray tstack(IT_NONE);
|
||||||
|
|
||||||
CheckFunc = !strcmp(mIdent->mString, "bv");
|
CheckFunc = !strcmp(mIdent->mString, "main");
|
||||||
|
|
||||||
mEntryBlock = mBlocks[0];
|
mEntryBlock = mBlocks[0];
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::Dereference(InterCodeProcedure*
|
||||||
ins->mSrc[0].mOperandSize = v.mReference == 1 ? v.mType->mSize : 2;
|
ins->mSrc[0].mOperandSize = v.mReference == 1 ? v.mType->mSize : 2;
|
||||||
ins->mSrc[0].mStride = v.mReference == 1 ? v.mType->mStripe : 1;
|
ins->mSrc[0].mStride = v.mReference == 1 ? v.mType->mStripe : 1;
|
||||||
|
|
||||||
|
if (ins->mDst.mType == IT_NONE)
|
||||||
|
{
|
||||||
|
mErrors->Error(exp->mLocation, EERR_INVALID_VALUE, "Not a simple type");
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
if (v.mReference == 1 && v.mType->mType == DT_TYPE_ENUM)
|
if (v.mReference == 1 && v.mType->mType == DT_TYPE_ENUM)
|
||||||
{
|
{
|
||||||
ins->mDst.mRange.LimitMin(v.mType->mMinValue);
|
ins->mDst.mRange.LimitMin(v.mType->mMinValue);
|
||||||
|
@ -1641,6 +1647,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EX_PACK:
|
case EX_PACK:
|
||||||
|
case EX_PACK_TYPE:
|
||||||
mErrors->Error(exp->mLocation, EERR_INVALID_PACK_USAGE, "Invalid pack usage");
|
mErrors->Error(exp->mLocation, EERR_INVALID_PACK_USAGE, "Invalid pack usage");
|
||||||
return ExValue(TheVoidTypeDeclaration);
|
return ExValue(TheVoidTypeDeclaration);
|
||||||
|
|
||||||
|
@ -2032,7 +2039,10 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
if (exp->mToken == TK_ASSIGN || !(vl.mType->mType == DT_TYPE_POINTER && vr.mType->IsIntegerType() && (exp->mToken == TK_ASSIGN_ADD || exp->mToken == TK_ASSIGN_SUB)))
|
if (exp->mToken == TK_ASSIGN || !(vl.mType->mType == DT_TYPE_POINTER && vr.mType->IsIntegerType() && (exp->mToken == TK_ASSIGN_ADD || exp->mToken == TK_ASSIGN_SUB)))
|
||||||
{
|
{
|
||||||
if (!vl.mType->CanAssign(vr.mType))
|
if (!vl.mType->CanAssign(vr.mType))
|
||||||
|
{
|
||||||
|
vl.mType->CanAssign(vr.mType);
|
||||||
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types");
|
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exp->mType != EX_INITIALIZATION && (vl.mType->mFlags & DTF_CONST))
|
if (exp->mType != EX_INITIALIZATION && (vl.mType->mFlags & DTF_CONST))
|
||||||
|
@ -3754,10 +3764,19 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
{
|
{
|
||||||
vr = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
vr = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
||||||
|
|
||||||
|
if (vr.mType->IsReference())
|
||||||
|
{
|
||||||
|
vr.mReference++;
|
||||||
|
vr.mType = vr.mType->mBase;
|
||||||
|
}
|
||||||
|
|
||||||
vr = Dereference(proc, exp, block, vr, 1);
|
vr = Dereference(proc, exp, block, vr, 1);
|
||||||
|
|
||||||
vr = CoerceType(proc, exp, block, vr, procType->mBase);
|
vr = CoerceType(proc, exp, block, vr, procType->mBase);
|
||||||
|
|
||||||
|
if (vr.mReference == 0)
|
||||||
|
mErrors->Error(exp->mLocation, EERR_INVALID_VALUE, "Returning value as reference");
|
||||||
|
|
||||||
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[0].mMemory = IM_INDIRECT;
|
||||||
|
@ -3766,18 +3785,28 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
{
|
{
|
||||||
if (inlineMapper->mResultExp)
|
if (inlineMapper->mResultExp)
|
||||||
{
|
{
|
||||||
ins->mSrc[1].mType = IT_POINTER;
|
if (inlineMapper->mResultExp->mType->IsReference())
|
||||||
ins->mSrc[1].mTemp = inlineMapper->mResultExp->mTemp;
|
{
|
||||||
ins->mSrc[1].mMemory = IM_INDIRECT;
|
ins->mSrc[1].mType = IT_POINTER;
|
||||||
ins->mCode = IC_STORE;
|
ins->mSrc[1].mTemp = inlineMapper->mResultExp->mTemp;
|
||||||
ins->mSrc[1].mOperandSize = 2;
|
ins->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
ins->mNumOperands = 2;
|
ins->mCode = IC_STORE;
|
||||||
|
ins->mSrc[1].mOperandSize = 2;
|
||||||
|
ins->mNumOperands = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//bool moving = exp->mLeft->IsRValue() || exp->mLeft->mType == EX_VARIABLE && !(exp->mLeft->mDecValue->mFlags & (DTF_STATIC | DTF_GLOBAL)) && exp->mLeft->mDecType->mType != DT_TYPE_REFERENCE;
|
||||||
|
|
||||||
|
CopyStruct(proc, exp, block, *(inlineMapper->mResultExp), vr, inlineMapper, false);
|
||||||
|
ins->mCode = IC_NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||||
ains->mDst.mType = IT_POINTER;
|
ains->mDst.mType = IT_POINTER;
|
||||||
ains->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
|
ains->mDst.mTemp = proc->AddTemporary(ains->mDst.mType);
|
||||||
ains->mConst.mType = IT_POINTER;
|
ains->mConst.mType = IT_POINTER;
|
||||||
ains->mConst.mOperandSize = procType->mBase->mSize;
|
ains->mConst.mOperandSize = procType->mBase->mSize;
|
||||||
ains->mConst.mIntConst = 0;
|
ains->mConst.mIntConst = 0;
|
||||||
|
@ -4007,7 +4036,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
{
|
{
|
||||||
InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||||
ains->mDst.mType = IT_POINTER;
|
ains->mDst.mType = IT_POINTER;
|
||||||
ains->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
|
ains->mDst.mTemp = proc->AddTemporary(ains->mDst.mType);
|
||||||
ains->mConst.mType = IT_POINTER;
|
ains->mConst.mType = IT_POINTER;
|
||||||
ains->mConst.mOperandSize = procType->mBase->mSize;
|
ains->mConst.mOperandSize = procType->mBase->mSize;
|
||||||
ains->mConst.mIntConst = 0;
|
ains->mConst.mIntConst = 0;
|
||||||
|
@ -4148,14 +4177,24 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
vc = Dereference(proc, exp, block, vc);
|
vc = Dereference(proc, exp, block, vc);
|
||||||
|
|
||||||
int ttemp;
|
int ttemp, tref = 0;
|
||||||
InterType ttype, stypel, styper;
|
InterType ttype, stypel, styper;
|
||||||
|
|
||||||
stypel = InterTypeOf(vl.mType);
|
stypel = InterTypeOf(vl.mType);
|
||||||
styper = InterTypeOf(vr.mType);
|
styper = InterTypeOf(vr.mType);
|
||||||
|
|
||||||
Declaration* dtype;
|
Declaration* dtype = exp->mDecType;
|
||||||
if (stypel == IT_POINTER || styper == IT_POINTER)
|
|
||||||
|
if (dtype->IsReference())
|
||||||
|
{
|
||||||
|
vl = Dereference(proc, exp, block, vl, 1);
|
||||||
|
vr = Dereference(proc, exp, block, vr, 1);
|
||||||
|
tref = 1;
|
||||||
|
|
||||||
|
dtype = dtype->mBase;
|
||||||
|
ttype = IT_POINTER;
|
||||||
|
}
|
||||||
|
else if (stypel == IT_POINTER || styper == IT_POINTER)
|
||||||
{
|
{
|
||||||
if (vl.mType->mType == DT_TYPE_ARRAY)
|
if (vl.mType->mType == DT_TYPE_ARRAY)
|
||||||
vl = Dereference(proc, exp, block, vl, 1);
|
vl = Dereference(proc, exp, block, vl, 1);
|
||||||
|
@ -4224,7 +4263,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
sins->mDst.mTemp = ttemp;
|
sins->mDst.mTemp = ttemp;
|
||||||
block->Append(sins);
|
block->Append(sins);
|
||||||
|
|
||||||
return ExValue(dtype, ttemp);
|
return ExValue(dtype, ttemp, tref);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -91,6 +91,7 @@ protected:
|
||||||
|
|
||||||
Declaration* ParseQualIdent(void);
|
Declaration* ParseQualIdent(void);
|
||||||
|
|
||||||
|
void SkipStatement(void);
|
||||||
Expression* ParseStatement(void);
|
Expression* ParseStatement(void);
|
||||||
Expression* ParseSwitchStatement(void);
|
Expression* ParseSwitchStatement(void);
|
||||||
|
|
||||||
|
@ -109,6 +110,7 @@ protected:
|
||||||
void ParseTemplateDeclarationBody(Declaration* tdec, Declaration* pthis);
|
void ParseTemplateDeclarationBody(Declaration* tdec, Declaration* pthis);
|
||||||
Declaration* FunctionAutoParamsToTemplate(Declaration* fdec);
|
Declaration* FunctionAutoParamsToTemplate(Declaration* fdec);
|
||||||
|
|
||||||
|
int ExpansionDistance(Declaration* tdec, Declaration* spec);
|
||||||
Declaration* ParseTemplateExpansion(Declaration* tmpld, Declaration* expd);
|
Declaration* ParseTemplateExpansion(Declaration* tmpld, Declaration* expd);
|
||||||
void CompleteTemplateExpansion(Declaration* tmpld);
|
void CompleteTemplateExpansion(Declaration* tmpld);
|
||||||
|
|
||||||
|
|
|
@ -148,6 +148,7 @@ const char* TokenNames[] =
|
||||||
"'#repeat'",
|
"'#repeat'",
|
||||||
"'#until'",
|
"'#until'",
|
||||||
"'#embed'",
|
"'#embed'",
|
||||||
|
"'#for'",
|
||||||
"'##'",
|
"'##'",
|
||||||
|
|
||||||
"'namespace'",
|
"'namespace'",
|
||||||
|
@ -596,6 +597,84 @@ void Scanner::NextPreToken(void)
|
||||||
mPreprocessor->CloseSource();
|
mPreprocessor->CloseSource();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (mToken == TK_PREP_FOR)
|
||||||
|
{
|
||||||
|
NextRawToken();
|
||||||
|
if (mToken == TK_OPEN_PARENTHESIS)
|
||||||
|
{
|
||||||
|
NextRawToken();
|
||||||
|
Macro* macro = new Macro(Ident::Unique("@for"), nullptr);
|
||||||
|
if (mToken == TK_IDENT)
|
||||||
|
{
|
||||||
|
const Ident* loopindex = mTokenIdent;
|
||||||
|
NextRawToken();
|
||||||
|
|
||||||
|
if (mToken == TK_COMMA)
|
||||||
|
{
|
||||||
|
mPreprocessorMode = true;
|
||||||
|
NextToken();
|
||||||
|
int64 loopCount = PrepParseConditional();
|
||||||
|
mPreprocessorMode = false;
|
||||||
|
|
||||||
|
if (mToken == TK_CLOSE_PARENTHESIS)
|
||||||
|
{
|
||||||
|
int slen = mOffset;
|
||||||
|
bool quote = false;
|
||||||
|
while (mLine[slen] && (quote || mLine[slen] != '/' || mLine[slen + 1] != '/'))
|
||||||
|
{
|
||||||
|
if (mLine[slen] == '"')
|
||||||
|
quote = !quote;
|
||||||
|
slen++;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro->SetString(mLine + mOffset, slen - mOffset);
|
||||||
|
|
||||||
|
mOffset = slen;
|
||||||
|
while (mLine[mOffset])
|
||||||
|
mOffset++;
|
||||||
|
|
||||||
|
if (loopCount > 0)
|
||||||
|
{
|
||||||
|
MacroExpansion* ex = new MacroExpansion();
|
||||||
|
MacroDict* scope = mDefineArguments;
|
||||||
|
mDefineArguments = new MacroDict();
|
||||||
|
|
||||||
|
Macro* arg = new Macro(loopindex, scope);
|
||||||
|
mDefineArguments->Insert(arg);
|
||||||
|
|
||||||
|
arg->SetString("0");
|
||||||
|
|
||||||
|
ex->mLine = mLine;
|
||||||
|
ex->mOffset = mOffset;
|
||||||
|
ex->mLink = mMacroExpansion;
|
||||||
|
ex->mChar = mTokenChar;
|
||||||
|
ex->mLoopCount = 0;
|
||||||
|
ex->mLoopIndex = arg;
|
||||||
|
ex->mLoopLimit = loopCount;
|
||||||
|
|
||||||
|
mMacroExpansion = ex;
|
||||||
|
mMacroExpansionDepth++;
|
||||||
|
if (mMacroExpansionDepth > 1024)
|
||||||
|
mErrors->Error(mLocation, EFATAL_MACRO_EXPANSION_DEPTH, "Maximum macro expansion depth exceeded", mTokenIdent);
|
||||||
|
mLine = macro->mString;
|
||||||
|
mOffset = 0;
|
||||||
|
NextChar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "')' expected in defined parameter list");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "',' expected");
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "'loop index variable expected");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "'('(' expected");
|
||||||
|
|
||||||
|
}
|
||||||
else if (mToken == TK_PREP_DEFINE)
|
else if (mToken == TK_PREP_DEFINE)
|
||||||
{
|
{
|
||||||
NextRawToken();
|
NextRawToken();
|
||||||
|
@ -1313,6 +1392,8 @@ void Scanner::NextRawToken(void)
|
||||||
mToken = TK_PREP_UNTIL;
|
mToken = TK_PREP_UNTIL;
|
||||||
else if (!strcmp(tkprep, "embed"))
|
else if (!strcmp(tkprep, "embed"))
|
||||||
mToken = TK_PREP_EMBED;
|
mToken = TK_PREP_EMBED;
|
||||||
|
else if (!strcmp(tkprep, "for"))
|
||||||
|
mToken = TK_PREP_FOR;
|
||||||
else
|
else
|
||||||
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid preprocessor command", tkprep);
|
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid preprocessor command", tkprep);
|
||||||
}
|
}
|
||||||
|
@ -1912,6 +1993,19 @@ bool Scanner::NextChar(void)
|
||||||
{
|
{
|
||||||
if (mMacroExpansion)
|
if (mMacroExpansion)
|
||||||
{
|
{
|
||||||
|
if (mMacroExpansion->mLoopIndex)
|
||||||
|
{
|
||||||
|
mMacroExpansion->mLoopCount++;
|
||||||
|
if (mMacroExpansion->mLoopCount < mMacroExpansion->mLoopLimit)
|
||||||
|
{
|
||||||
|
char buffer[20];
|
||||||
|
sprintf_s(buffer, "%d", int(mMacroExpansion->mLoopCount));
|
||||||
|
mMacroExpansion->mLoopIndex->SetString(buffer);
|
||||||
|
mOffset = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MacroExpansion* mac = mMacroExpansion->mLink;
|
MacroExpansion* mac = mMacroExpansion->mLink;
|
||||||
// delete mDefineArguments;
|
// delete mDefineArguments;
|
||||||
|
|
||||||
|
|
|
@ -146,6 +146,7 @@ enum Token
|
||||||
TK_PREP_REPEAT,
|
TK_PREP_REPEAT,
|
||||||
TK_PREP_UNTIL,
|
TK_PREP_UNTIL,
|
||||||
TK_PREP_EMBED,
|
TK_PREP_EMBED,
|
||||||
|
TK_PREP_FOR,
|
||||||
|
|
||||||
TK_PREP_CONCAT,
|
TK_PREP_CONCAT,
|
||||||
|
|
||||||
|
@ -284,7 +285,14 @@ protected:
|
||||||
const char * mLine;
|
const char * mLine;
|
||||||
int mOffset;
|
int mOffset;
|
||||||
char mChar;
|
char mChar;
|
||||||
|
Macro * mLoopIndex;
|
||||||
|
int64 mLoopCount, mLoopLimit;
|
||||||
MacroDict* mDefinedArguments;
|
MacroDict* mDefinedArguments;
|
||||||
|
|
||||||
|
MacroExpansion(void)
|
||||||
|
: mLink(nullptr), mLine(nullptr), mOffset(0), mChar(0), mLoopIndex(nullptr), mLoopCount(0), mLoopLimit(0), mDefinedArguments(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
} * mMacroExpansion;
|
} * mMacroExpansion;
|
||||||
|
|
||||||
int mMacroExpansionDepth;
|
int mMacroExpansionDepth;
|
||||||
|
|
Loading…
Reference in New Issue