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,10 +453,13 @@ 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;
|
||||||
|
while (type)
|
||||||
|
{
|
||||||
for (Declaration* mdec = type->mParams; mdec; mdec = mdec->mNext)
|
for (Declaration* mdec = type->mParams; mdec; mdec = mdec->mNext)
|
||||||
{
|
{
|
||||||
Declaration * cdec = GetConst(offset + mdec->mOffset, mdec->mBase, dataSection);
|
Declaration* cdec = GetConst(offset + mdec->mOffset, mdec->mBase, dataSection);
|
||||||
cdec->mOffset = mdec->mOffset;
|
cdec->mOffset = mdec->mOffset;
|
||||||
|
|
||||||
if (ldec)
|
if (ldec)
|
||||||
|
@ -460,7 +468,12 @@ Declaration* ConstexprInterpreter::Value::GetConst(int offset, Declaration* type
|
||||||
dec->mParams = cdec;
|
dec->mParams = cdec;
|
||||||
|
|
||||||
ldec = cdec;
|
ldec = cdec;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type->mBase)
|
||||||
|
type = type->mBase->mBase;
|
||||||
|
else
|
||||||
|
type = nullptr;
|
||||||
}
|
}
|
||||||
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)
|
||||||
|
{
|
||||||
|
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);
|
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)
|
||||||
|
{
|
||||||
|
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);
|
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,8 +2039,11 @@ 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))
|
||||||
mErrors->Error(exp->mLocation, EERR_CONST_ASSIGN, "Cannot assign to const type");
|
mErrors->Error(exp->mLocation, EERR_CONST_ASSIGN, "Cannot assign to const type");
|
||||||
|
@ -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;
|
||||||
|
@ -3765,6 +3784,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
if (inlineMapper)
|
if (inlineMapper)
|
||||||
{
|
{
|
||||||
if (inlineMapper->mResultExp)
|
if (inlineMapper->mResultExp)
|
||||||
|
{
|
||||||
|
if (inlineMapper->mResultExp->mType->IsReference())
|
||||||
{
|
{
|
||||||
ins->mSrc[1].mType = IT_POINTER;
|
ins->mSrc[1].mType = IT_POINTER;
|
||||||
ins->mSrc[1].mTemp = inlineMapper->mResultExp->mTemp;
|
ins->mSrc[1].mTemp = inlineMapper->mResultExp->mTemp;
|
||||||
|
@ -3774,10 +3795,18 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
ins->mNumOperands = 2;
|
ins->mNumOperands = 2;
|
||||||
}
|
}
|
||||||
else
|
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
|
||||||
{
|
{
|
||||||
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
|
||||||
|
|
|
@ -595,6 +595,16 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
|
||||||
|
|
||||||
AddDefaultConstructors(pthis);
|
AddDefaultConstructors(pthis);
|
||||||
|
|
||||||
|
if (pthis->mBase->mConst)
|
||||||
|
{
|
||||||
|
pthis->mBase->mConst->mDestructor = pthis->mBase->mDestructor;
|
||||||
|
pthis->mBase->mConst->mDefaultConstructor = pthis->mBase->mDefaultConstructor;
|
||||||
|
pthis->mBase->mConst->mCopyConstructor = pthis->mBase->mCopyConstructor;
|
||||||
|
pthis->mBase->mConst->mMoveConstructor = pthis->mBase->mMoveConstructor;
|
||||||
|
pthis->mBase->mConst->mVectorConstructor = pthis->mBase->mVectorConstructor;
|
||||||
|
pthis->mBase->mConst->mVectorCopyConstructor = pthis->mBase->mVectorCopyConstructor;
|
||||||
|
}
|
||||||
|
|
||||||
// Lookup constructors, have same name as class
|
// Lookup constructors, have same name as class
|
||||||
Declaration* cdec = dec->mScope->Lookup(dec->mIdent->PreMangle("+"), SLEVEL_SCOPE);
|
Declaration* cdec = dec->mScope->Lookup(dec->mIdent->PreMangle("+"), SLEVEL_SCOPE);
|
||||||
while (cdec)
|
while (cdec)
|
||||||
|
@ -753,24 +763,26 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified, Decl
|
||||||
|
|
||||||
case TK_IDENT:
|
case TK_IDENT:
|
||||||
pident = mScanner->mTokenIdent;
|
pident = mScanner->mTokenIdent;
|
||||||
|
mScanner->NextToken();
|
||||||
|
|
||||||
if (mTemplateScope)
|
if (mTemplateScope)
|
||||||
dec = mTemplateScope->Lookup(mScanner->mTokenIdent);
|
{
|
||||||
|
dec = mTemplateScope->Lookup(pident);
|
||||||
|
if (dec && mScanner->mToken == TK_LESS_THAN && !dec->mTemplate)
|
||||||
|
dec = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (!dec)
|
if (!dec)
|
||||||
{
|
{
|
||||||
dec = mScope->Lookup(mScanner->mTokenIdent);
|
dec = mScope->Lookup(pident);
|
||||||
if (dec && dec->mType == DT_CONST_FUNCTION && mScope->mLevel == SLEVEL_CLASS)
|
if (dec && dec->mType == DT_CONST_FUNCTION && mScope->mLevel == SLEVEL_CLASS)
|
||||||
dec = mScope->mParent->Lookup(mScanner->mTokenIdent);
|
dec = mScope->mParent->Lookup(pident);
|
||||||
|
|
||||||
mScanner->NextToken();
|
|
||||||
|
|
||||||
dec = ParseBaseTypeQualify(qualified, dec, pident);
|
dec = ParseBaseTypeQualify(qualified, dec, pident);
|
||||||
|
|
||||||
if (dec && dec->mTemplate)
|
if (dec && dec->mTemplate)
|
||||||
dec = ParseTemplateExpansion(dec->mTemplate, nullptr);
|
dec = ParseTemplateExpansion(dec->mTemplate, nullptr);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
mScanner->NextToken();
|
|
||||||
|
|
||||||
dec = ParseBaseTypeQualify(qualified, dec, pident);
|
dec = ParseBaseTypeQualify(qualified, dec, pident);
|
||||||
|
|
||||||
|
@ -1191,7 +1203,7 @@ Declaration * Parser::ParseFunctionDeclaration(Declaration* bdec)
|
||||||
atdec = atdec->mBase;
|
atdec = atdec->mBase;
|
||||||
if (atdec->mType == DT_PACK_TYPE)
|
if (atdec->mType == DT_PACK_TYPE)
|
||||||
{
|
{
|
||||||
atdec = atdec->mBase;
|
atdec = atdec->mParams;
|
||||||
|
|
||||||
Declaration* apdec = adec;
|
Declaration* apdec = adec;
|
||||||
while (atdec)
|
while (atdec)
|
||||||
|
@ -1827,8 +1839,11 @@ Expression* Parser::BuildMemberInitializer(Expression* vexp)
|
||||||
nexp->mDecType = vexp->mDecType;
|
nexp->mDecType = vexp->mDecType;
|
||||||
nexp->mLeft = vexp;
|
nexp->mLeft = vexp;
|
||||||
ConsumeToken(TK_OPEN_PARENTHESIS);
|
ConsumeToken(TK_OPEN_PARENTHESIS);
|
||||||
|
if (!ConsumeTokenIf(TK_CLOSE_PARENTHESIS))
|
||||||
|
{
|
||||||
nexp->mRight = ParseRExpression();
|
nexp->mRight = ParseRExpression();
|
||||||
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
||||||
|
}
|
||||||
|
|
||||||
return nexp;
|
return nexp;
|
||||||
}
|
}
|
||||||
|
@ -2043,6 +2058,9 @@ void Parser::BuildMemberConstructor(Declaration* pthis, Declaration* cfunc)
|
||||||
scope->Insert(pdec->mIdent, pdec);
|
scope->Insert(pdec->mIdent, pdec);
|
||||||
pdec = pdec->mNext;
|
pdec = pdec->mNext;
|
||||||
}
|
}
|
||||||
|
if (cfunc->mBase->mParamPack)
|
||||||
|
mScope->Insert(cfunc->mBase->mParamPack->mIdent, cfunc->mBase->mParamPack);
|
||||||
|
|
||||||
Declaration* othis = mThisPointer;
|
Declaration* othis = mThisPointer;
|
||||||
mThisPointer = pthis;
|
mThisPointer = pthis;
|
||||||
|
|
||||||
|
@ -2165,6 +2183,12 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
|
||||||
if (!(bcdec->mBase->mCopyConstructor->mBase->mFlags & DTF_REQUEST_INLINE))
|
if (!(bcdec->mBase->mCopyConstructor->mBase->mFlags & DTF_REQUEST_INLINE))
|
||||||
inlineCopy = false;
|
inlineCopy = false;
|
||||||
}
|
}
|
||||||
|
if (bcdec->mBase->mMoveConstructor)
|
||||||
|
{
|
||||||
|
simpleMove = false;
|
||||||
|
if (!(bcdec->mBase->mMoveConstructor->mBase->mFlags & DTF_REQUEST_INLINE))
|
||||||
|
inlineCopy = false;
|
||||||
|
}
|
||||||
if (bcdec->mBase->mCopyAssignment)
|
if (bcdec->mBase->mCopyAssignment)
|
||||||
simpleAssignment = false;
|
simpleAssignment = false;
|
||||||
bcdec = bcdec->mNext;
|
bcdec = bcdec->mNext;
|
||||||
|
@ -2202,6 +2226,8 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
|
||||||
simpleCopy = false;
|
simpleCopy = false;
|
||||||
if (bdec->mCopyAssignment)
|
if (bdec->mCopyAssignment)
|
||||||
simpleAssignment = false;
|
simpleAssignment = false;
|
||||||
|
if (bdec->mMoveConstructor)
|
||||||
|
simpleMove = false;
|
||||||
}
|
}
|
||||||
if (dec->mValue)
|
if (dec->mValue)
|
||||||
simpleConstructor = false;
|
simpleConstructor = false;
|
||||||
|
@ -3242,16 +3268,18 @@ Expression* Parser::AddFunctionCallRefReturned(Expression* exp)
|
||||||
// Returning a value object for pass by address
|
// Returning a value object for pass by address
|
||||||
// add a temporary variable
|
// add a temporary variable
|
||||||
|
|
||||||
int nindex = mLocalIndex++;
|
//int nindex = mLocalIndex++;
|
||||||
|
|
||||||
Declaration* rtdec = exp->mLeft->mDecType;
|
Declaration* rtdec = exp->mLeft->mDecType;
|
||||||
|
|
||||||
|
Declaration* vdec = AllocTempVar(rtdec);
|
||||||
|
#if 0
|
||||||
Declaration* vdec = new Declaration(exp->mLocation, DT_VARIABLE);
|
Declaration* vdec = new Declaration(exp->mLocation, DT_VARIABLE);
|
||||||
|
|
||||||
vdec->mVarIndex = nindex;
|
vdec->mVarIndex = nindex;
|
||||||
vdec->mBase = rtdec;
|
vdec->mBase = rtdec;
|
||||||
vdec->mSize = rtdec->mSize;
|
vdec->mSize = rtdec->mSize;
|
||||||
|
#endif
|
||||||
Expression* vexp = new Expression(exp->mLocation, EX_VARIABLE);
|
Expression* vexp = new Expression(exp->mLocation, EX_VARIABLE);
|
||||||
vexp->mDecType = rtdec;
|
vexp->mDecType = rtdec;
|
||||||
vexp->mDecValue = vdec;
|
vexp->mDecValue = vdec;
|
||||||
|
@ -3293,16 +3321,18 @@ Expression* Parser::AddFunctionCallRefReturned(Expression* exp)
|
||||||
// Returning a value object for pass by address
|
// Returning a value object for pass by address
|
||||||
// add a temporary variable
|
// add a temporary variable
|
||||||
|
|
||||||
int nindex = mLocalIndex++;
|
// int nindex = mLocalIndex++;
|
||||||
|
|
||||||
Declaration* rtdec = exp->mLeft->mDecType;
|
Declaration* rtdec = exp->mLeft->mDecType;
|
||||||
|
|
||||||
|
Declaration* vdec = AllocTempVar(rtdec);
|
||||||
|
#if 0
|
||||||
Declaration* vdec = new Declaration(exp->mLocation, DT_VARIABLE);
|
Declaration* vdec = new Declaration(exp->mLocation, DT_VARIABLE);
|
||||||
|
|
||||||
vdec->mVarIndex = nindex;
|
vdec->mVarIndex = nindex;
|
||||||
vdec->mBase = rtdec;
|
vdec->mBase = rtdec;
|
||||||
vdec->mSize = rtdec->mSize;
|
vdec->mSize = rtdec->mSize;
|
||||||
|
#endif
|
||||||
Expression* vexp = new Expression(exp->mLocation, EX_VARIABLE);
|
Expression* vexp = new Expression(exp->mLocation, EX_VARIABLE);
|
||||||
vexp->mDecType = rtdec;
|
vexp->mDecType = rtdec;
|
||||||
vexp->mDecValue = vdec;
|
vexp->mDecValue = vdec;
|
||||||
|
@ -3361,16 +3391,18 @@ Expression* Parser::AddFunctionCallRefReturned(Expression* exp)
|
||||||
// Returning a value object for pass as reference
|
// Returning a value object for pass as reference
|
||||||
// add a temporary variable
|
// add a temporary variable
|
||||||
|
|
||||||
|
Declaration* vdec = AllocTempVar(pex->mDecType);
|
||||||
|
#if 0
|
||||||
int nindex = mLocalIndex++;
|
int nindex = mLocalIndex++;
|
||||||
|
|
||||||
Declaration* vdec = new Declaration(exp->mLocation, DT_VARIABLE);
|
Declaration* vdec = new Declaration(exp->mLocation, DT_VARIABLE);
|
||||||
|
|
||||||
vdec->mVarIndex = nindex;
|
vdec->mVarIndex = nindex;
|
||||||
vdec->mBase = pdec->mBase->mBase;
|
vdec->mBase = pex->mDecType;
|
||||||
vdec->mSize = pdec->mBase->mBase->mSize;
|
vdec->mSize = pex->mDecType->mSize;
|
||||||
|
#endif
|
||||||
Expression* vexp = new Expression(pex->mLocation, EX_VARIABLE);
|
Expression* vexp = new Expression(pex->mLocation, EX_VARIABLE);
|
||||||
vexp->mDecType = pdec->mBase->mBase;
|
vexp->mDecType = pex->mDecType;
|
||||||
vexp->mDecValue = vdec;
|
vexp->mDecValue = vdec;
|
||||||
|
|
||||||
Expression* cexp = new Expression(pex->mLocation, pex->mType);
|
Expression* cexp = new Expression(pex->mLocation, pex->mType);
|
||||||
|
@ -3450,6 +3482,28 @@ Expression* Parser::AddFunctionCallRefReturned(Expression* exp)
|
||||||
pex->mDecType = vdec->mBase;
|
pex->mDecType = vdec->mBase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ((pdec->mBase->mType == DT_TYPE_REFERENCE && !pex->IsConstRef()) || (pdec->mBase->mType == DT_TYPE_RVALUEREF && !pex->IsLValue()))
|
||||||
|
{
|
||||||
|
Declaration* vdec = AllocTempVar(pex->mDecType);
|
||||||
|
|
||||||
|
Expression* vexp = new Expression(pex->mLocation, EX_VARIABLE);
|
||||||
|
vexp->mDecType = pex->mDecType;
|
||||||
|
vexp->mDecValue = vdec;
|
||||||
|
|
||||||
|
Expression* cexp = new Expression(pex->mLocation, pex->mType);
|
||||||
|
cexp->mDecType = pex->mDecType;
|
||||||
|
cexp->mDecValue = pex->mDecValue;
|
||||||
|
cexp->mLeft = pex->mLeft;
|
||||||
|
cexp->mRight = pex->mRight;
|
||||||
|
cexp->mToken = pex->mToken;
|
||||||
|
|
||||||
|
pex->mType = EX_INITIALIZATION;
|
||||||
|
pex->mToken = TK_ASSIGN;
|
||||||
|
pex->mLeft = vexp;
|
||||||
|
pex->mRight = cexp;
|
||||||
|
pex->mDecValue = nullptr;
|
||||||
|
pex->mDecType = vdec->mBase;
|
||||||
|
}
|
||||||
|
|
||||||
pdec = pdec->mNext;
|
pdec = pdec->mNext;
|
||||||
}
|
}
|
||||||
|
@ -3753,7 +3807,15 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
||||||
if (ctdec->mParams)
|
if (ctdec->mParams)
|
||||||
mErrors->Error(ctdec->mLocation, EERR_WRONG_PARAMETER, "Cast operators can't have parameter");
|
mErrors->Error(ctdec->mLocation, EERR_WRONG_PARAMETER, "Cast operators can't have parameter");
|
||||||
|
|
||||||
PrependThisArgument(ctdec, pthis);
|
Declaration* bthis = new Declaration(mScanner->mLocation, DT_TYPE_POINTER);
|
||||||
|
bthis->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||||
|
if (ConsumeTokenIf(TK_CONST))
|
||||||
|
bthis->mBase = pthis->mBase->ToConstType();
|
||||||
|
else
|
||||||
|
bthis->mBase = pthis->mBase;
|
||||||
|
bthis->mSize = 2;
|
||||||
|
|
||||||
|
PrependThisArgument(ctdec, bthis);
|
||||||
|
|
||||||
Declaration* cdec = new Declaration(ctdec->mLocation, DT_CONST_FUNCTION);
|
Declaration* cdec = new Declaration(ctdec->mLocation, DT_CONST_FUNCTION);
|
||||||
cdec->mBase = ctdec;
|
cdec->mBase = ctdec;
|
||||||
|
@ -4995,6 +5057,21 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TK_CONST:
|
case TK_CONST:
|
||||||
|
if (lhs)
|
||||||
|
exp = ParseDeclarationExpression(nullptr);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mScanner->NextToken();
|
||||||
|
exp = new Expression(mScanner->mLocation, EX_TYPE);
|
||||||
|
exp->mDecValue = nullptr;
|
||||||
|
exp->mDecType = ParseBaseTypeDeclaration(DTF_CONST, true);
|
||||||
|
while (ConsumeTokenIf(TK_MUL))
|
||||||
|
exp->mDecType = exp->mDecType->BuildPointer(mScanner->mLocation);
|
||||||
|
while (ConsumeTokenIf(TK_BINARY_AND))
|
||||||
|
exp->mDecType = exp->mDecType->BuildReference(mScanner->mLocation);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case TK_VOLATILE:
|
case TK_VOLATILE:
|
||||||
case TK_STRUCT:
|
case TK_STRUCT:
|
||||||
case TK_CLASS:
|
case TK_CLASS:
|
||||||
|
@ -5314,6 +5391,12 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
|
||||||
exp->mDecValue = dec;
|
exp->mDecValue = dec;
|
||||||
exp->mDecType = dec->mBase;
|
exp->mDecType = dec->mBase;
|
||||||
}
|
}
|
||||||
|
else if (dec->mType == DT_PACK_TYPE)
|
||||||
|
{
|
||||||
|
exp = new Expression(mScanner->mLocation, EX_PACK_TYPE);
|
||||||
|
exp->mDecValue = nullptr;
|
||||||
|
exp->mDecType = dec;
|
||||||
|
}
|
||||||
else if (dec->mType <= DT_TYPE_FUNCTION)
|
else if (dec->mType <= DT_TYPE_FUNCTION)
|
||||||
{
|
{
|
||||||
if (lhs)
|
if (lhs)
|
||||||
|
@ -5335,6 +5418,11 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
|
||||||
exp->mDecValue = dec;
|
exp->mDecValue = dec;
|
||||||
exp->mDecType = TheSignedIntTypeDeclaration;
|
exp->mDecType = TheSignedIntTypeDeclaration;
|
||||||
}
|
}
|
||||||
|
else if (dec->mType == DT_PACK_TEMPLATE)
|
||||||
|
{
|
||||||
|
exp = new Expression(mScanner->mLocation, EX_PACK_TYPE);
|
||||||
|
exp->mDecType = dec;
|
||||||
|
}
|
||||||
else if (dec->mType == DT_ELEMENT)
|
else if (dec->mType == DT_ELEMENT)
|
||||||
{
|
{
|
||||||
mErrors->Error(mScanner->mLocation, EERR_NON_STATIC_MEMBER, "Non static member access", mScanner->mTokenIdent);
|
mErrors->Error(mScanner->mLocation, EERR_NON_STATIC_MEMBER, "Non static member access", mScanner->mTokenIdent);
|
||||||
|
@ -5411,6 +5499,7 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
|
||||||
Expression* nexp = new Expression(mScanner->mLocation, EX_TYPECAST);
|
Expression* nexp = new Expression(mScanner->mLocation, EX_TYPECAST);
|
||||||
nexp->mDecType = exp->mDecType;
|
nexp->mDecType = exp->mDecType;
|
||||||
nexp->mLeft = ParsePrefixExpression(false);
|
nexp->mLeft = ParsePrefixExpression(false);
|
||||||
|
nexp = CheckOperatorOverload(nexp);
|
||||||
exp = nexp->ConstantFold(mErrors, mDataSection);
|
exp = nexp->ConstantFold(mErrors, mDataSection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5514,6 +5603,7 @@ Expression* Parser::ParseQualify(Expression* exp)
|
||||||
uint64 mflags = 0;
|
uint64 mflags = 0;
|
||||||
Declaration* mdec = nullptr;
|
Declaration* mdec = nullptr;
|
||||||
const Ident* ident = nullptr;
|
const Ident* ident = nullptr;
|
||||||
|
bool destructor = false;
|
||||||
|
|
||||||
if ((mCompilerOptions & COPT_CPLUSPLUS) && mScanner->mToken == TK_BINARY_NOT)
|
if ((mCompilerOptions & COPT_CPLUSPLUS) && mScanner->mToken == TK_BINARY_NOT)
|
||||||
{
|
{
|
||||||
|
@ -5529,6 +5619,7 @@ Expression* Parser::ParseQualify(Expression* exp)
|
||||||
}
|
}
|
||||||
|
|
||||||
ident = ident->PreMangle("~");
|
ident = ident->PreMangle("~");
|
||||||
|
destructor = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Identifier expected");
|
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Identifier expected");
|
||||||
|
@ -5628,6 +5719,12 @@ Expression* Parser::ParseQualify(Expression* exp)
|
||||||
exp = nexp;
|
exp = nexp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (destructor)
|
||||||
|
{
|
||||||
|
mScanner->NextToken();
|
||||||
|
ConsumeToken(TK_OPEN_PARENTHESIS);
|
||||||
|
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Struct member identifier not found", mScanner->mTokenIdent);
|
mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Struct member identifier not found", mScanner->mTokenIdent);
|
||||||
|
@ -5808,6 +5905,12 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
|
||||||
else
|
else
|
||||||
return NOOVERLOAD;
|
return NOOVERLOAD;
|
||||||
|
|
||||||
|
if (ptype->mBase->mTemplate)
|
||||||
|
{
|
||||||
|
dist += 16;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
int ncast = 0;
|
int ncast = 0;
|
||||||
Declaration* ext = ex->mDecType;
|
Declaration* ext = ex->mDecType;
|
||||||
while (ext && !ext->IsConstSame(ptype->mBase))
|
while (ext && !ext->IsConstSame(ptype->mBase))
|
||||||
|
@ -5826,6 +5929,7 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
|
||||||
else
|
else
|
||||||
return NOOVERLOAD;
|
return NOOVERLOAD;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (ptype->mType == DT_TYPE_POINTER && (etype->mType == DT_TYPE_ARRAY || etype->mType == DT_TYPE_POINTER) && ptype->mBase->IsSameMutable(etype->mBase))
|
else if (ptype->mType == DT_TYPE_POINTER && (etype->mType == DT_TYPE_ARRAY || etype->mType == DT_TYPE_POINTER) && ptype->mBase->IsSameMutable(etype->mBase))
|
||||||
dist += 2;
|
dist += 2;
|
||||||
else if (ptype->mType == DT_TYPE_POINTER && etype->mType == DT_TYPE_FUNCTION && ptype->mBase->IsSame(etype))
|
else if (ptype->mType == DT_TYPE_POINTER && etype->mType == DT_TYPE_FUNCTION && ptype->mBase->IsSame(etype))
|
||||||
|
@ -5912,7 +6016,7 @@ bool Parser::CanCoerceExpression(Expression* exp, Declaration* type)
|
||||||
{
|
{
|
||||||
if (!type->IsConstSame(tdec))
|
if (!type->IsConstSame(tdec))
|
||||||
{
|
{
|
||||||
Declaration* fcons = type->mScope->Lookup(type->mIdent->PreMangle("+"));
|
Declaration* fcons = type->mScope ? type->mScope->Lookup(type->mIdent->PreMangle("+")) : nullptr;
|
||||||
if (fcons)
|
if (fcons)
|
||||||
{
|
{
|
||||||
while (fcons && !(fcons->mBase->mParams && fcons->mBase->mParams->mNext && !fcons->mBase->mParams->mNext->mNext && fcons->mBase->mParams->mNext->mBase->CanAssign(tdec)))
|
while (fcons && !(fcons->mBase->mParams && fcons->mBase->mParams->mNext && !fcons->mBase->mParams->mNext->mNext && fcons->mBase->mParams->mNext->mBase->CanAssign(tdec)))
|
||||||
|
@ -6148,7 +6252,12 @@ Expression * Parser::ResolveOverloadCall(Expression* exp, Expression* exp2)
|
||||||
if (ibest == NOOVERLOAD)
|
if (ibest == NOOVERLOAD)
|
||||||
{
|
{
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
|
fdec = exp->mLeft->mDecValue;
|
||||||
|
while (fdec)
|
||||||
|
{
|
||||||
int d = OverloadDistance(exp->mLeft->mDecValue, exp->mRight);
|
int d = OverloadDistance(exp->mLeft->mDecValue, exp->mRight);
|
||||||
|
fdec = fdec->mNext;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
mErrors->Error(exp->mLocation, ERRO_NO_MATCHING_FUNCTION_CALL, "No matching function call", exp->mLeft->mDecValue->mQualIdent);
|
mErrors->Error(exp->mLocation, ERRO_NO_MATCHING_FUNCTION_CALL, "No matching function call", exp->mLeft->mDecValue->mQualIdent);
|
||||||
}
|
}
|
||||||
|
@ -6301,6 +6410,7 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
|
||||||
Expression* nexp = new Expression(mScanner->mLocation, EX_TYPECAST);
|
Expression* nexp = new Expression(mScanner->mLocation, EX_TYPECAST);
|
||||||
nexp->mDecType = exp->mDecType;
|
nexp->mDecType = exp->mDecType;
|
||||||
nexp->mLeft = pexp;
|
nexp->mLeft = pexp;
|
||||||
|
nexp = CheckOperatorOverload(nexp);
|
||||||
exp = nexp->ConstantFold(mErrors, mDataSection);
|
exp = nexp->ConstantFold(mErrors, mDataSection);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -6639,19 +6749,32 @@ Expression* Parser::ParseNewOperator(void)
|
||||||
if (mScanner->mToken == TK_OPEN_PARENTHESIS || dec->mDefaultConstructor)
|
if (mScanner->mToken == TK_OPEN_PARENTHESIS || dec->mDefaultConstructor)
|
||||||
{
|
{
|
||||||
Declaration* mdec = dec->mDefaultConstructor;
|
Declaration* mdec = dec->mDefaultConstructor;
|
||||||
|
Expression* pexp = nullptr;
|
||||||
|
|
||||||
bool plist = false;
|
|
||||||
if (ConsumeTokenIf(TK_OPEN_PARENTHESIS))
|
if (ConsumeTokenIf(TK_OPEN_PARENTHESIS))
|
||||||
{
|
{
|
||||||
if (!ConsumeTokenIf(TK_CLOSE_PARENTHESIS))
|
if (!ConsumeTokenIf(TK_CLOSE_PARENTHESIS))
|
||||||
{
|
{
|
||||||
plist = true;
|
pexp = ParseListExpression(false);
|
||||||
|
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (dec->mType == DT_TYPE_STRUCT)
|
if (dec->mType == DT_TYPE_STRUCT)
|
||||||
mdec = dec->mScope->Lookup(dec->mIdent->PreMangle("+"));
|
{
|
||||||
|
mdec = dec->mScope ? dec->mScope->Lookup(dec->mIdent->PreMangle("+")) : nullptr;
|
||||||
|
if (pexp && pexp->mType != EX_LIST)
|
||||||
|
{
|
||||||
|
if (pexp->mDecType->IsSame(dec))
|
||||||
|
mdec = dec->mCopyConstructor;
|
||||||
|
else if (pexp->mDecType->mType == DT_TYPE_REFERENCE && pexp->mDecType->mBase->IsSame(dec))
|
||||||
|
mdec = dec->mCopyConstructor;
|
||||||
|
else if (pexp->mDecType->mType == DT_TYPE_RVALUEREF && pexp->mDecType->mBase->IsSame(dec))
|
||||||
|
mdec = dec->mMoveConstructor;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
mdec = nullptr;
|
mdec = nullptr;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mdec)
|
if (mdec)
|
||||||
{
|
{
|
||||||
|
@ -6670,19 +6793,10 @@ Expression* Parser::ParseNewOperator(void)
|
||||||
iexp->mRight = nexp;
|
iexp->mRight = nexp;
|
||||||
iexp->mDecType = nexp->mDecType;
|
iexp->mDecType = nexp->mDecType;
|
||||||
|
|
||||||
Expression* pexp = vexp;
|
|
||||||
|
|
||||||
if (plist)
|
|
||||||
{
|
|
||||||
pexp = ParseListExpression(false);
|
|
||||||
|
|
||||||
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
|
||||||
|
|
||||||
Expression* lexp = new Expression(mScanner->mLocation, EX_LIST);
|
Expression* lexp = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
lexp->mLeft = vexp;
|
lexp->mLeft = vexp;
|
||||||
lexp->mRight = pexp;
|
lexp->mRight = pexp;
|
||||||
pexp = lexp;
|
pexp = lexp;
|
||||||
}
|
|
||||||
|
|
||||||
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
cexp->mDecValue = mdec;
|
cexp->mDecValue = mdec;
|
||||||
|
@ -6718,12 +6832,7 @@ Expression* Parser::ParseNewOperator(void)
|
||||||
nexp->mRight = coexp;
|
nexp->mRight = coexp;
|
||||||
nexp->mDecType = coexp->mDecType;
|
nexp->mDecType = coexp->mDecType;
|
||||||
}
|
}
|
||||||
else if (plist && !mdec)
|
else if (pexp && pexp->mType != EX_LIST)
|
||||||
{
|
|
||||||
Expression * pexp = ParseListExpression(false);
|
|
||||||
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
|
||||||
|
|
||||||
if (pexp && pexp->mType != EX_LIST)
|
|
||||||
{
|
{
|
||||||
Expression* dexp = new Expression(mScanner->mLocation, EX_PREFIX);
|
Expression* dexp = new Expression(mScanner->mLocation, EX_PREFIX);
|
||||||
dexp->mToken = TK_MUL;
|
dexp->mToken = TK_MUL;
|
||||||
|
@ -6736,14 +6845,12 @@ Expression* Parser::ParseNewOperator(void)
|
||||||
iexp->mRight = pexp;
|
iexp->mRight = pexp;
|
||||||
iexp->mDecType = nexp->mDecType;
|
iexp->mDecType = nexp->mDecType;
|
||||||
|
|
||||||
nexp = iexp;
|
nexp = new Expression(mScanner->mLocation, EX_PREFIX);
|
||||||
|
nexp->mToken = TK_BINARY_AND;
|
||||||
|
nexp->mDecType = nexp->mDecType;
|
||||||
|
nexp->mLeft = iexp;
|
||||||
}
|
}
|
||||||
else
|
else if (pexp)
|
||||||
mErrors->Error(mScanner->mLocation, ERRO_NO_MATCHING_FUNCTION_CALL, "No matching constructor", dec->mIdent);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (plist)
|
|
||||||
{
|
{
|
||||||
mErrors->Error(mScanner->mLocation, ERRO_NO_MATCHING_FUNCTION_CALL, "No matching constructor", dec->mIdent);
|
mErrors->Error(mScanner->mLocation, ERRO_NO_MATCHING_FUNCTION_CALL, "No matching constructor", dec->mIdent);
|
||||||
}
|
}
|
||||||
|
@ -7880,6 +7987,56 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (exp->mType == EX_TYPECAST)
|
||||||
|
{
|
||||||
|
Declaration* tdec = exp->mLeft->mDecType;
|
||||||
|
if (exp->mLeft->mDecType)
|
||||||
|
{
|
||||||
|
while (tdec->mType == DT_TYPE_REFERENCE || tdec->mType == DT_TYPE_RVALUEREF)
|
||||||
|
tdec = tdec->mBase;
|
||||||
|
|
||||||
|
if (tdec->mType == DT_TYPE_STRUCT)
|
||||||
|
{
|
||||||
|
Declaration* mdec = tdec->mScope->Lookup(Ident::Unique("(cast)"));
|
||||||
|
while (mdec && !mdec->mBase->mBase->IsSame(exp->mDecType))
|
||||||
|
mdec = mdec->mNext;
|
||||||
|
while (!mdec && tdec->mBase && tdec->mBase->mBase)
|
||||||
|
{
|
||||||
|
tdec = tdec->mBase->mBase;
|
||||||
|
mdec = tdec->mScope->Lookup(Ident::Unique("(cast)"));
|
||||||
|
while (mdec && !mdec->mBase->mBase->IsSame(exp->mDecType))
|
||||||
|
mdec = mdec->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mdec)
|
||||||
|
{
|
||||||
|
Expression* nexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
|
||||||
|
nexp->mLeft = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
nexp->mLeft->mDecType = mdec->mBase;
|
||||||
|
nexp->mLeft->mDecValue = mdec;
|
||||||
|
|
||||||
|
nexp->mDecType = mdec->mBase;
|
||||||
|
nexp->mRight = exp->mRight;
|
||||||
|
|
||||||
|
Expression* texp = new Expression(nexp->mLocation, EX_PREFIX);
|
||||||
|
texp->mToken = TK_BINARY_AND;
|
||||||
|
texp->mLeft = exp->mLeft;
|
||||||
|
texp->mDecType = new Declaration(nexp->mLocation, DT_TYPE_POINTER);
|
||||||
|
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||||
|
texp->mDecType->mBase = tdec;
|
||||||
|
texp->mDecType->mSize = 2;
|
||||||
|
|
||||||
|
nexp->mRight = texp->ConstantFold(mErrors, mDataSection);
|
||||||
|
|
||||||
|
nexp = ResolveOverloadCall(nexp);
|
||||||
|
nexp->mDecType = nexp->mLeft->mDecType->mBase;
|
||||||
|
|
||||||
|
exp = nexp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (exp->mType == EX_LOGICAL_NOT)
|
else if (exp->mType == EX_LOGICAL_NOT)
|
||||||
{
|
{
|
||||||
const Ident* opident = Ident::Unique("operator!");
|
const Ident* opident = Ident::Unique("operator!");
|
||||||
|
@ -8133,6 +8290,30 @@ Expression* Parser::ParseFunction(Declaration * dec)
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Parser::SkipStatement(void)
|
||||||
|
{
|
||||||
|
if (ConsumeTokenIf(TK_OPEN_BRACE))
|
||||||
|
{
|
||||||
|
int cnt = 1;
|
||||||
|
while (cnt > 0)
|
||||||
|
{
|
||||||
|
if (ConsumeTokenIf(TK_OPEN_BRACE))
|
||||||
|
cnt++;
|
||||||
|
else if (ConsumeTokenIf(TK_CLOSE_BRACE))
|
||||||
|
cnt--;
|
||||||
|
else
|
||||||
|
mScanner->NextToken();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (!ConsumeTokenIf(TK_SEMICOLON))
|
||||||
|
{
|
||||||
|
mScanner->NextToken();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Expression* Parser::ParseStatement(void)
|
Expression* Parser::ParseStatement(void)
|
||||||
{
|
{
|
||||||
Expression* exp = nullptr;
|
Expression* exp = nullptr;
|
||||||
|
@ -8202,7 +8383,32 @@ Expression* Parser::ParseStatement(void)
|
||||||
case TK_IF:
|
case TK_IF:
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
bool constExp = ConsumeTokenIf(TK_CONSTEXPR);
|
|
||||||
|
if (ConsumeTokenIf(TK_CONSTEXPR))
|
||||||
|
{
|
||||||
|
exp = CoerceExpression(CleanupExpression(ParseParenthesisExpression()), TheBoolTypeDeclaration)->ConstantFold(mErrors, mDataSection);
|
||||||
|
if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_INTEGER)
|
||||||
|
{
|
||||||
|
if (exp->mDecValue->mInteger)
|
||||||
|
{
|
||||||
|
exp = ParseStatement();
|
||||||
|
if (ConsumeTokenIf(TK_ELSE))
|
||||||
|
SkipStatement();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SkipStatement();
|
||||||
|
if (ConsumeTokenIf(TK_ELSE))
|
||||||
|
exp = ParseStatement();
|
||||||
|
else
|
||||||
|
exp = new Expression(mScanner->mLocation, EX_VOID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(exp->mLocation, EERR_INVALID_CONSTEXPR, "Condition is not constant");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
exp = new Expression(mScanner->mLocation, EX_IF);
|
exp = new Expression(mScanner->mLocation, EX_IF);
|
||||||
exp->mLeft = CoerceExpression(CleanupExpression(ParseParenthesisExpression()), TheBoolTypeDeclaration);
|
exp->mLeft = CoerceExpression(CleanupExpression(ParseParenthesisExpression()), TheBoolTypeDeclaration);
|
||||||
exp->mRight = new Expression(mScanner->mLocation, EX_ELSE);
|
exp->mRight = new Expression(mScanner->mLocation, EX_ELSE);
|
||||||
|
@ -8214,22 +8420,8 @@ Expression* Parser::ParseStatement(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
exp->mRight->mRight = nullptr;
|
exp->mRight->mRight = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (constExp)
|
|
||||||
{
|
|
||||||
Expression * cexp = exp->mLeft->ConstantFold(mErrors, mDataSection);
|
|
||||||
if (cexp->mType == EX_CONSTANT && cexp->mDecValue->mType == DT_CONST_INTEGER)
|
|
||||||
{
|
|
||||||
if (cexp->mDecValue->mInteger)
|
|
||||||
exp = exp->mRight->mLeft;
|
|
||||||
else if (exp->mRight->mRight)
|
|
||||||
exp = exp->mRight->mRight;
|
|
||||||
else
|
|
||||||
exp = new Expression(mScanner->mLocation, EX_VOID);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mErrors->Error(exp->mLocation, EERR_INVALID_CONSTEXPR, "Condition is not constant");
|
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
case TK_WHILE:
|
case TK_WHILE:
|
||||||
{
|
{
|
||||||
|
@ -8663,9 +8855,10 @@ Expression* Parser::ParseStatement(void)
|
||||||
exp->mLeft = ParseRExpression();
|
exp->mLeft = ParseRExpression();
|
||||||
if (mFunctionType && mFunctionType->mBase)
|
if (mFunctionType && mFunctionType->mBase)
|
||||||
{
|
{
|
||||||
if (mFunctionType->mBase->mType == DT_TYPE_AUTO)
|
if (mFunctionType->mBase->mType == DT_TYPE_AUTO || mFunctionType->mBase->IsReference() && mFunctionType->mBase->mBase->mType == DT_TYPE_AUTO)
|
||||||
{
|
{
|
||||||
mFunctionType->mBase = exp->mLeft->mDecType;
|
mFunctionType->mBase = mFunctionType->mBase->DeduceAuto(exp->mLeft->mDecType);
|
||||||
|
;
|
||||||
if (mFunctionType->mBase->mType == DT_TYPE_STRUCT)
|
if (mFunctionType->mBase->mType == DT_TYPE_STRUCT)
|
||||||
{
|
{
|
||||||
// Make room for value struct return
|
// Make room for value struct return
|
||||||
|
@ -8835,11 +9028,323 @@ Expression* Parser::ParseSwitchStatement(void)
|
||||||
return sexp;
|
return sexp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Parser::ExpansionDistance(Declaration* tdec, Declaration* spec)
|
||||||
|
{
|
||||||
|
Declaration* ptdec = tdec->mParams;
|
||||||
|
Declaration* psdec = spec->mParams;
|
||||||
|
|
||||||
|
int cost = 0;
|
||||||
|
if (tdec->mParser)
|
||||||
|
cost = 100000;
|
||||||
|
|
||||||
|
while (ptdec && psdec)
|
||||||
|
{
|
||||||
|
if (ptdec->mType == DT_CONST_TEMPLATE && psdec->mType == DT_CONST_TEMPLATE)
|
||||||
|
{
|
||||||
|
if (ptdec->mBase)
|
||||||
|
{
|
||||||
|
if (ptdec->mBase->mInteger != psdec->mBase->mInteger)
|
||||||
|
return NOOVERLOAD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cost += 100;
|
||||||
|
}
|
||||||
|
else if (ptdec->mType == DT_TYPE_TEMPLATE && psdec->mType == DT_TYPE_TEMPLATE)
|
||||||
|
{
|
||||||
|
if (ptdec->mBase)
|
||||||
|
{
|
||||||
|
if (!ptdec->mBase->IsSame(psdec->mBase))
|
||||||
|
return NOOVERLOAD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cost += 100;
|
||||||
|
}
|
||||||
|
else if (ptdec->mType == DT_PACK_TEMPLATE && psdec->mType == DT_PACK_TEMPLATE)
|
||||||
|
{
|
||||||
|
if (ptdec->mBase)
|
||||||
|
{
|
||||||
|
|
||||||
|
Declaration* tvp = ptdec->mBase->mParams;
|
||||||
|
Declaration* svp = psdec->mBase->mParams;
|
||||||
|
|
||||||
|
while (tvp && svp && tvp->IsSame(svp))
|
||||||
|
{
|
||||||
|
tvp = tvp->mNext;
|
||||||
|
svp = svp->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tvp || svp)
|
||||||
|
return NOOVERLOAD;
|
||||||
|
}
|
||||||
|
else if (psdec->mBase)
|
||||||
|
{
|
||||||
|
Declaration* dec = psdec->mBase->mParams;
|
||||||
|
while (dec)
|
||||||
|
{
|
||||||
|
cost += 200;
|
||||||
|
dec = dec->mNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ptdec->mType == DT_PACK_TEMPLATE)
|
||||||
|
{
|
||||||
|
if (ptdec->mBase)
|
||||||
|
{
|
||||||
|
ptdec = ptdec->mBase->mParams;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (psdec)
|
||||||
|
{
|
||||||
|
cost += 200;
|
||||||
|
psdec = psdec->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NOOVERLOAD;
|
||||||
|
|
||||||
|
ptdec = ptdec->mNext;
|
||||||
|
psdec = psdec->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptdec && ptdec->mType == DT_PACK_TEMPLATE)
|
||||||
|
{
|
||||||
|
if (ptdec->mBase)
|
||||||
|
{
|
||||||
|
if (ptdec->mBase->mParams)
|
||||||
|
return NOOVERLOAD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cost += 50;
|
||||||
|
}
|
||||||
|
else if (ptdec || psdec)
|
||||||
|
return NOOVERLOAD;
|
||||||
|
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* expd)
|
Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* expd)
|
||||||
{
|
{
|
||||||
Declaration * tdec = new Declaration(mScanner->mLocation, DT_TEMPLATE);
|
Declaration * tdec = new Declaration(mScanner->mLocation, DT_TEMPLATE);
|
||||||
tdec->mScope = new DeclarationScope(nullptr, SLEVEL_TEMPLATE);
|
tdec->mScope = new DeclarationScope(nullptr, SLEVEL_TEMPLATE);
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
if (expd)
|
||||||
|
{
|
||||||
|
if (tmpld->mBase->mType == DT_TEMPLATE)
|
||||||
|
{
|
||||||
|
Parser* p = tmpld->mBase->mParser->Clone();
|
||||||
|
|
||||||
|
p->mScanner->Replay(tmpld->mBase->mTokens);
|
||||||
|
|
||||||
|
tdec = tmpld->mBase->Clone();
|
||||||
|
tdec->mScope->mName = expd->mScope->mName;
|
||||||
|
tdec->mScope->mParent = expd->mScope;
|
||||||
|
|
||||||
|
p->ParseTemplateDeclarationBody(tdec, nullptr);
|
||||||
|
|
||||||
|
return tdec;
|
||||||
|
}
|
||||||
|
|
||||||
|
Declaration* ppdec = nullptr;
|
||||||
|
Declaration* dec = expd->mParams;
|
||||||
|
|
||||||
|
while (dec)
|
||||||
|
{
|
||||||
|
Declaration* epdec = dec->Clone();
|
||||||
|
|
||||||
|
if (ppdec)
|
||||||
|
ppdec->mNext = epdec;
|
||||||
|
else
|
||||||
|
tdec->mParams = epdec;
|
||||||
|
ppdec = epdec;
|
||||||
|
|
||||||
|
dec = dec->mNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ConsumeToken(TK_LESS_THAN);
|
||||||
|
|
||||||
|
Declaration* ppdec = nullptr;
|
||||||
|
|
||||||
|
if (!ConsumeTokenIf(TK_GREATER_THAN))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Expression* exp = ParseShiftExpression(false);
|
||||||
|
Declaration* pdec = nullptr;
|
||||||
|
|
||||||
|
if (exp->mType == EX_TYPE)
|
||||||
|
{
|
||||||
|
pdec = new Declaration(exp->mLocation, DT_TYPE_TEMPLATE);
|
||||||
|
pdec->mBase = exp->mDecType;
|
||||||
|
}
|
||||||
|
else if (exp->mType == EX_PACK_TYPE)
|
||||||
|
{
|
||||||
|
ConsumeToken(TK_ELLIPSIS);
|
||||||
|
|
||||||
|
if (exp->mDecType->mType == DT_PACK_TYPE)
|
||||||
|
{
|
||||||
|
Declaration* ptdec = exp->mDecType->mParams;
|
||||||
|
while (ptdec)
|
||||||
|
{
|
||||||
|
pdec = new Declaration(exp->mLocation, DT_TYPE_TEMPLATE);
|
||||||
|
pdec->mBase = ptdec;
|
||||||
|
|
||||||
|
if (pdec)
|
||||||
|
{
|
||||||
|
if (ppdec)
|
||||||
|
ppdec->mNext = pdec;
|
||||||
|
else
|
||||||
|
tdec->mParams = pdec;
|
||||||
|
ppdec = pdec;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptdec = ptdec->mNext;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pdec = new Declaration(exp->mLocation, DT_PACK_TEMPLATE);
|
||||||
|
pdec->mBase = exp->mDecType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_FUNCTION)
|
||||||
|
{
|
||||||
|
pdec = new Declaration(exp->mLocation, DT_TYPE_TEMPLATE);
|
||||||
|
pdec->mBase = exp->mDecValue;
|
||||||
|
}
|
||||||
|
else if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_INTEGER)
|
||||||
|
{
|
||||||
|
pdec = new Declaration(exp->mLocation, DT_CONST_TEMPLATE);
|
||||||
|
pdec->mBase = exp->mDecValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(exp->mLocation, EERR_TEMPLATE_PARAMS, "Template specification expected");
|
||||||
|
|
||||||
|
if (pdec)
|
||||||
|
{
|
||||||
|
if (ppdec)
|
||||||
|
ppdec->mNext = pdec;
|
||||||
|
else
|
||||||
|
tdec->mParams = pdec;
|
||||||
|
ppdec = pdec;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (ConsumeTokenIf(TK_COMMA));
|
||||||
|
|
||||||
|
ConsumeToken(TK_GREATER_THAN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!tmpld->mTokens)
|
||||||
|
tmpld = tmpld->mNext;
|
||||||
|
|
||||||
|
Declaration* epdec = tdec->mParams;
|
||||||
|
while (epdec && epdec->mBase && epdec->mBase->mType != DT_TYPE_TEMPLATE && epdec->mBase->mType != DT_CONST_TEMPLATE && epdec->mBase->mType != DT_PACK_TEMPLATE)
|
||||||
|
epdec = epdec->mNext;
|
||||||
|
|
||||||
|
if (epdec)
|
||||||
|
{
|
||||||
|
// Partial template specification
|
||||||
|
Declaration* bdec = new Declaration(mScanner->mLocation, tmpld->mBase->mType);
|
||||||
|
tdec->mBase = bdec;
|
||||||
|
bdec->mTemplate = tdec;
|
||||||
|
bdec->mBase = tmpld->mBase->mBase;
|
||||||
|
tdec->mNext = tmpld;
|
||||||
|
bdec->mIdent = tdec->MangleIdent();
|
||||||
|
|
||||||
|
return bdec;
|
||||||
|
}
|
||||||
|
|
||||||
|
Declaration* pthis = tmpld->mClass;
|
||||||
|
|
||||||
|
int mindist = NOOVERLOAD;
|
||||||
|
Declaration* etdec = nullptr;
|
||||||
|
|
||||||
|
Declaration* dec = tmpld;
|
||||||
|
while (dec)
|
||||||
|
{
|
||||||
|
int dist = ExpansionDistance(dec, tdec);
|
||||||
|
if (dist < mindist)
|
||||||
|
{
|
||||||
|
mindist = dist;
|
||||||
|
etdec = dec;
|
||||||
|
}
|
||||||
|
dec = dec->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mindist == 0)
|
||||||
|
return etdec->mBase;
|
||||||
|
else if (mindist == NOOVERLOAD)
|
||||||
|
mErrors->Error(tdec->mLocation, EERR_TEMPLATE_PARAMS, "No matching template parameters");
|
||||||
|
else
|
||||||
|
tmpld = etdec;
|
||||||
|
|
||||||
|
dec = tdec->mParams;
|
||||||
|
Declaration * pdec = tmpld->mParams;
|
||||||
|
|
||||||
|
Declaration * ppdec = nullptr;
|
||||||
|
while (pdec)
|
||||||
|
{
|
||||||
|
if (pdec->mType == DT_PACK_TEMPLATE)
|
||||||
|
{
|
||||||
|
if (!dec)
|
||||||
|
{
|
||||||
|
Declaration* packd = new Declaration(tdec->mLocation, DT_PACK_TEMPLATE);
|
||||||
|
packd->mBase = new Declaration(tdec->mLocation, DT_PACK_TYPE);
|
||||||
|
if (ppdec)
|
||||||
|
ppdec->mNext = packd;
|
||||||
|
else
|
||||||
|
tdec->mParams = packd;
|
||||||
|
dec = packd;
|
||||||
|
}
|
||||||
|
else if (dec->mType != DT_PACK_TEMPLATE)
|
||||||
|
{
|
||||||
|
Declaration* packd = new Declaration(dec->mLocation, DT_PACK_TEMPLATE);
|
||||||
|
packd->mBase = new Declaration(dec->mLocation, DT_PACK_TYPE);
|
||||||
|
if (ppdec)
|
||||||
|
ppdec->mNext = packd;
|
||||||
|
else
|
||||||
|
tdec->mParams = packd;
|
||||||
|
|
||||||
|
ppdec = nullptr;
|
||||||
|
while (dec)
|
||||||
|
{
|
||||||
|
Declaration* ndec = dec->mBase->Clone();
|
||||||
|
|
||||||
|
if (ppdec)
|
||||||
|
ppdec->mNext = ndec;
|
||||||
|
else
|
||||||
|
packd->mBase->mParams = ndec;
|
||||||
|
ppdec = ndec;
|
||||||
|
dec = dec->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
dec = packd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dec)
|
||||||
|
{
|
||||||
|
dec->mIdent = pdec->mIdent;
|
||||||
|
tdec->mScope->Insert(dec->mIdent, dec->mBase);
|
||||||
|
|
||||||
|
ppdec = dec;
|
||||||
|
dec = dec->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdec = pdec->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
if (expd)
|
if (expd)
|
||||||
{
|
{
|
||||||
if (tmpld->mBase->mType == DT_TEMPLATE)
|
if (tmpld->mBase->mType == DT_TEMPLATE)
|
||||||
|
@ -8971,28 +9476,7 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
||||||
Declaration* etdec = tmpld->mNext;
|
Declaration* etdec = tmpld->mNext;
|
||||||
while (etdec && !etdec->IsSameParams(tdec))
|
while (etdec && !etdec->IsSameParams(tdec))
|
||||||
etdec = etdec->mNext;
|
etdec = etdec->mNext;
|
||||||
if (etdec)
|
#endif
|
||||||
{
|
|
||||||
return etdec->mBase;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Declaration* epdec = tdec->mParams;
|
|
||||||
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, tmpld->mBase->mType);
|
|
||||||
tdec->mBase = bdec;
|
|
||||||
bdec->mTemplate = tdec;
|
|
||||||
bdec->mBase = tmpld->mBase->mBase;
|
|
||||||
tdec->mNext = tmpld;
|
|
||||||
bdec->mIdent = tdec->MangleIdent();
|
|
||||||
|
|
||||||
return bdec;
|
|
||||||
}
|
|
||||||
|
|
||||||
Parser* p = tmpld->mParser->Clone();
|
Parser* p = tmpld->mParser->Clone();
|
||||||
|
|
||||||
|
@ -9076,7 +9560,6 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
||||||
}
|
}
|
||||||
|
|
||||||
return tdec->mBase;
|
return tdec->mBase;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::CompleteTemplateExpansion(Declaration* tmpld)
|
void Parser::CompleteTemplateExpansion(Declaration* tmpld)
|
||||||
|
@ -9121,7 +9604,7 @@ Declaration* Parser::FunctionAutoParamsToTemplate(Declaration* fdec)
|
||||||
{
|
{
|
||||||
Declaration* tdec = new Declaration(fdec->mLocation, DT_TEMPLATE);
|
Declaration* tdec = new Declaration(fdec->mLocation, DT_TEMPLATE);
|
||||||
tdec->mParser = this->Clone();
|
tdec->mParser = this->Clone();
|
||||||
tdec->mScope = new DeclarationScope(nullptr, SLEVEL_TEMPLATE);
|
tdec->mScope = new DeclarationScope(mTemplateScope, SLEVEL_TEMPLATE);
|
||||||
Declaration* ppdec = nullptr;
|
Declaration* ppdec = nullptr;
|
||||||
|
|
||||||
int ntp = 0;
|
int ntp = 0;
|
||||||
|
@ -9221,6 +9704,8 @@ Declaration * Parser::ParseTemplateDeclaration(Declaration* pthis)
|
||||||
Declaration* ppdec = nullptr;
|
Declaration* ppdec = nullptr;
|
||||||
|
|
||||||
ConsumeToken(TK_LESS_THAN);
|
ConsumeToken(TK_LESS_THAN);
|
||||||
|
if (mScanner->mToken != TK_GREATER_THAN)
|
||||||
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Declaration* pdec = nullptr;
|
Declaration* pdec = nullptr;
|
||||||
|
@ -9276,6 +9761,7 @@ Declaration * Parser::ParseTemplateDeclaration(Declaration* pthis)
|
||||||
if (!ConsumeTokenIf(TK_COMMA))
|
if (!ConsumeTokenIf(TK_COMMA))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ConsumeToken(TK_GREATER_THAN);
|
ConsumeToken(TK_GREATER_THAN);
|
||||||
|
|
||||||
|
@ -9295,7 +9781,7 @@ Declaration * Parser::ParseTemplateDeclaration(Declaration* pthis)
|
||||||
void Parser::ParseTemplateDeclarationBody(Declaration * tdec, Declaration * pthis)
|
void Parser::ParseTemplateDeclarationBody(Declaration * tdec, Declaration * pthis)
|
||||||
{
|
{
|
||||||
mScanner->BeginRecord();
|
mScanner->BeginRecord();
|
||||||
if (mScanner->mToken == TK_CLASS)
|
if (mScanner->mToken == TK_CLASS || mScanner->mToken == TK_STRUCT)
|
||||||
{
|
{
|
||||||
// Class template
|
// Class template
|
||||||
Declaration* bdec = new Declaration(mScanner->mLocation, DT_TYPE_STRUCT);
|
Declaration* bdec = new Declaration(mScanner->mLocation, DT_TYPE_STRUCT);
|
||||||
|
@ -9404,7 +9890,24 @@ void Parser::ParseTemplateDeclarationBody(Declaration * tdec, Declaration * pthi
|
||||||
tdec->mScope->mName = tdec->mQualIdent;
|
tdec->mScope->mName = tdec->mQualIdent;
|
||||||
|
|
||||||
if (tdec->mQualIdent == mScope->Mangle(tdec->mIdent))
|
if (tdec->mQualIdent == mScope->Mangle(tdec->mIdent))
|
||||||
mScope->Insert(tdec->mIdent, tdec->mBase);
|
{
|
||||||
|
Declaration* pdec = mScope->Insert(tdec->mIdent, tdec->mBase);
|
||||||
|
if (pdec)
|
||||||
|
{
|
||||||
|
Declaration* ppdec = pdec;
|
||||||
|
while (pdec && !pdec->IsSameTemplate(tdec->mBase))
|
||||||
|
{
|
||||||
|
ppdec = pdec;
|
||||||
|
pdec = pdec->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pdec && pdec->mTemplate)
|
||||||
|
{
|
||||||
|
tdec->mNext = pdec->mTemplate->mNext;
|
||||||
|
pdec->mTemplate->mNext = tdec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Declaration* pdec = mCompilationUnits->mScope->Insert(tdec->mQualIdent, tdec->mBase);
|
Declaration* pdec = mCompilationUnits->mScope->Insert(tdec->mQualIdent, tdec->mBase);
|
||||||
if (pdec)
|
if (pdec)
|
||||||
|
|
|
@ -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