Add RValue Reference

This commit is contained in:
drmortalwombat 2023-08-13 20:53:39 +02:00
parent 61f8b68c2f
commit 80426d974c
9 changed files with 189 additions and 34 deletions

View File

@ -1,11 +1,10 @@
#ifndef OPP_MOVE_H #ifndef OPP_MOVE_H
#define OPP_MOVE_H #define OPP_MOVE_H
template <class T> template <class T>
void move(T & dst, T & src) T && move(T & m)
{ {
dst = src; return (T &&)m;
} }
#endif #endif

View File

@ -31,6 +31,12 @@ string::string(const string & s)
cstr = nullptr; cstr = nullptr;
} }
string::string(string && s)
: cstr(s.cstr)
{
s.cstr = nullptr;
}
string::string(const char * s) string::string(const char * s)
{ {
if (s) if (s)
@ -104,6 +110,18 @@ string & string::operator=(const string & s)
return *this; return *this;
} }
string & string::operator=(string && s)
{
if (cstr != s.cstr)
{
free(cstr);
cstr = s.cstr;
s.cstr = nullptr;
}
return *this;
}
string & string::operator=(const char * s) string & string::operator=(const char * s)
{ {
free(cstr); free(cstr);

View File

@ -9,6 +9,7 @@ private:
public: public:
string(void); string(void);
string(const string & s); string(const string & s);
string(string && s);
string(const char * s); string(const char * s);
string(const char * s, char size); string(const char * s, char size);
string(char c); string(char c);
@ -17,6 +18,7 @@ public:
unsigned size(void) const; unsigned size(void) const;
string & operator=(const string & s); string & operator=(const string & s);
string & operator=(string && s);
string & operator=(const char * s); string & operator=(const char * s);
string & operator+=(const string & s); string & operator+=(const string & s);

View File

@ -2,6 +2,7 @@
#define OPP_VECTOR_H #define OPP_VECTOR_H
#include <stdlib.h> #include <stdlib.h>
#include <opp/move.h>
template <class T> template <class T>
class vector class vector
@ -101,6 +102,8 @@ public:
void push_back(const T & t); void push_back(const T & t);
void push_back(T && t);
void pop_back(void) void pop_back(void)
{ {
_size--; _size--;
@ -121,7 +124,7 @@ void vector<T>::reserve(int n)
T * d = (T *)malloc(_capacity * sizeof(T)); T * d = (T *)malloc(_capacity * sizeof(T));
for(int i=0; i<_size; i++) for(int i=0; i<_size; i++)
{ {
new (d + i)T(_data[i]); new (d + i)T(move(_data[i]));
_data[i].~T(); _data[i].~T();
} }
free(_data); free(_data);
@ -160,7 +163,7 @@ void vector<T>::shrink_to_fit(void)
T * d = (T *)malloc(_capacity * sizeof(T)); T * d = (T *)malloc(_capacity * sizeof(T));
for(int i=0; i<_size; i++) for(int i=0; i<_size; i++)
{ {
new (d + i)T(_data[i]); new (d + i)T(move(_data[i]));
_data[i].~T(); _data[i].~T();
} }
free(_data); free(_data);
@ -176,6 +179,14 @@ void vector<T>::push_back(const T & t)
new (_data + _size++)T(t); new (_data + _size++)T(t);
} }
template <class T>
void vector<T>::push_back(T && t)
{
if (_size == _capacity)
reserve(_size + 1 + (_size >> 1));
new (_data + _size++)T(t);
}
template <class T> template <class T>
void vector<T>::insert(int at, const T & t) void vector<T>::insert(int at, const T & t)
{ {
@ -183,7 +194,7 @@ void vector<T>::insert(int at, const T & t)
reserve(_size + 1 + (_size >> 1)); reserve(_size + 1 + (_size >> 1));
new (_data + _size)T; new (_data + _size)T;
for(int i=_size; i>at; i--) for(int i=_size; i>at; i--)
_data[i] = _data[i - 1]; _data[i] = move(_data[i - 1]);
_data[at] = t; _data[at] = t;
} }
@ -192,7 +203,7 @@ void vector<T>::erase(int at, int n)
{ {
_size -= n; _size -= n;
for(int i=at; i<_size; i++) for(int i=at; i<_size; i++)
_data[i] = _data[i + n]; _data[i] = move(_data[i + n]);
_data[_size].~T(); _data[_size].~T();
} }

View File

@ -919,7 +919,7 @@ Declaration* Declaration::BuildConstRValueRef(const Location& loc)
DecType Declaration::ValueType(void) const DecType Declaration::ValueType(void) const
{ {
if (mType == DT_TYPE_REFERENCE || mType == DT_TYPE_RVALUEREF) if (IsReference())
return mBase->mType; return mBase->mType;
else else
return mType; return mType;
@ -1334,7 +1334,7 @@ bool Declaration::IsSubType(const Declaration* dec) const
if (this == dec) if (this == dec)
return true; return true;
if (mType == DT_TYPE_REFERENCE && dec->mType == DT_TYPE_REFERENCE) if (IsReference() && dec->IsReference())
return mBase->IsSubType(dec->mBase); return mBase->IsSubType(dec->mBase);
if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY) if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
@ -1510,6 +1510,26 @@ bool Declaration::IsConstSame(const Declaration* dec) const
return false; return false;
} }
bool Declaration::IsTemplateSameParams(const Declaration* dec, const Declaration* tdec) const
{
if (mType == DT_TYPE_FUNCTION && dec->mType == DT_TYPE_FUNCTION)
{
// Skip this pointer for now
Declaration* ld = mParams->mNext, * rd = dec->mParams;
while (ld && rd)
{
if (!ld->mBase->IsTemplateSame(rd->mBase, tdec))
return false;
ld = ld->mNext;
rd = rd->mNext;
}
return !ld && !rd;
}
else
return false;
}
bool Declaration::IsSameParams(const Declaration* dec) const bool Declaration::IsSameParams(const Declaration* dec) const
{ {
if (mType == DT_TYPE_FUNCTION && dec->mType == DT_TYPE_FUNCTION || mType == DT_TEMPLATE && dec->mType == DT_TEMPLATE) if (mType == DT_TYPE_FUNCTION && dec->mType == DT_TYPE_FUNCTION || mType == DT_TEMPLATE && dec->mType == DT_TEMPLATE)
@ -1587,7 +1607,7 @@ bool Declaration::IsSame(const Declaration* dec) const
else else
return this->Stride() == dec->Stride() && mBase->IsSame(dec->mBase); return this->Stride() == dec->Stride() && mBase->IsSame(dec->mBase);
} }
else if (mType == DT_TYPE_REFERENCE) else if (IsReference())
return mBase->IsSame(dec->mBase); return mBase->IsSame(dec->mBase);
else if (mType == DT_TYPE_STRUCT) else if (mType == DT_TYPE_STRUCT)
return mScope == dec->mScope || (mIdent == dec->mIdent && mSize == dec->mSize); return mScope == dec->mScope || (mIdent == dec->mIdent && mSize == dec->mSize);
@ -1616,6 +1636,72 @@ bool Declaration::IsSame(const Declaration* dec) const
return false; return false;
} }
bool Declaration::IsTemplateSame(const Declaration* dec, const Declaration * tdec) const
{
if (dec->mType == DT_TYPE_TEMPLATE)
dec = tdec->mScope->Lookup(dec->mIdent);
if (this == dec)
return true;
if (mType != dec->mType)
return false;
if (mSize != dec->mSize)
return false;
if (mStripe != dec->mStripe)
return false;
if ((mFlags & (DTF_SIGNED | DTF_CONST | DTF_VOLATILE)) != (dec->mFlags & (DTF_SIGNED | DTF_CONST | DTF_VOLATILE)))
return false;
if (mType == DT_TYPE_INTEGER)
return true;
else if (mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_VOID)
return true;
else if (mType == DT_TYPE_ENUM)
return mIdent == dec->mIdent;
else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
{
if (mBase->mType == DT_TYPE_STRUCT && dec->mBase->mType == DT_TYPE_STRUCT && mBase->mStripe == dec->mBase->mStripe)
{
if (mBase->mQualIdent == dec->mBase->mQualIdent &&
(mBase->mFlags & (DTF_CONST | DTF_VOLATILE)) == (dec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE)))
return true;
else
return false;
}
else
return this->Stride() == dec->Stride() && mBase->IsTemplateSame(dec->mBase, tdec);
}
else if (IsReference())
return mBase->IsTemplateSame(dec->mBase, tdec);
else if (mType == DT_TYPE_STRUCT)
return mScope == dec->mScope || (mIdent == dec->mIdent && mSize == dec->mSize);
else if (mType == DT_TYPE_FUNCTION)
{
if (!mBase->IsTemplateSame(dec->mBase, tdec))
return false;
Declaration* dl = mParams, * dr = dec->mParams;
while (dl && dr)
{
if (!dl->mBase->IsTemplateSame(dr->mBase, tdec))
return false;
dl = dl->mNext;
dr = dr->mNext;
}
if (dl || dr)
return false;
if ((mFlags & DTF_VARIADIC) != (dec->mFlags & DTF_VARIADIC))
return false;
return true;
}
return false;
}
bool Declaration::IsSameValue(const Declaration* dec) const bool Declaration::IsSameValue(const Declaration* dec) const
{ {
if (mType != dec->mType || mSize != dec->mSize) if (mType != dec->mType || mSize != dec->mSize)
@ -1638,9 +1724,9 @@ bool Declaration::IsSameValue(const Declaration* dec) const
bool Declaration::CanAssign(const Declaration* fromType) const bool Declaration::CanAssign(const Declaration* fromType) const
{ {
if (fromType->mType == DT_TYPE_REFERENCE) if (fromType->IsReference())
return this->CanAssign(fromType->mBase); return this->CanAssign(fromType->mBase);
if (mType == DT_TYPE_REFERENCE) if (IsReference())
return mBase->IsSubType(fromType); return mBase->IsSubType(fromType);
if (this->IsSame(fromType)) if (this->IsSame(fromType))
@ -1695,6 +1781,11 @@ bool Declaration::IsNumericType(void) const
} }
bool Declaration::IsReference(void) const
{
return mType == DT_TYPE_REFERENCE || mType == DT_TYPE_RVALUEREF;
}
bool Declaration::IsSimpleType(void) const bool Declaration::IsSimpleType(void) const
{ {
return mType == DT_TYPE_INTEGER || mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_ENUM || mType == DT_TYPE_POINTER; return mType == DT_TYPE_INTEGER || mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_ENUM || mType == DT_TYPE_POINTER;

View File

@ -283,9 +283,13 @@ public:
bool IsSameParams(const Declaration* dec) const; bool IsSameParams(const Declaration* dec) const;
bool IsSameMutable(const Declaration* dec) const; bool IsSameMutable(const Declaration* dec) const;
bool IsTemplateSame(const Declaration* dec, const Declaration* tdec) const;
bool IsTemplateSameParams(const Declaration* dec, const Declaration* tdec) const;
bool IsIntegerType(void) const; bool IsIntegerType(void) const;
bool IsNumericType(void) const; bool IsNumericType(void) const;
bool IsSimpleType(void) const; bool IsSimpleType(void) const;
bool IsReference(void) const;
void SetDefined(void); void SetDefined(void);

View File

@ -4532,7 +4532,8 @@ void InterCodeBasicBlock::Append(InterInstruction * code)
assert(code->mConst.mVarIndex < mProc->mModule->mGlobalVars.Size()); assert(code->mConst.mVarIndex < mProc->mModule->mGlobalVars.Size());
assert(mProc->mModule->mGlobalVars[code->mConst.mVarIndex]); assert(mProc->mModule->mGlobalVars[code->mConst.mVarIndex]);
} }
if (code->mDst.mTemp >= 0)
assert(code->mDst.mType != IT_NONE);
for (int i = 0; i < code->mNumOperands; i++) for (int i = 0; i < code->mNumOperands; i++)
assert(code->mSrc[i].mType != IT_NONE); assert(code->mSrc[i].mType != IT_NONE);
@ -16748,7 +16749,7 @@ void InterCodeProcedure::Close(void)
{ {
GrowingTypeArray tstack(IT_NONE); GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "join"); CheckFunc = !strcmp(mIdent->mString, "main");
mEntryBlock = mBlocks[0]; mEntryBlock = mBlocks[0];

View File

@ -34,13 +34,14 @@ static inline InterType InterTypeOf(const Declaration* dec)
case DT_TYPE_FUNCTION: case DT_TYPE_FUNCTION:
case DT_TYPE_ARRAY: case DT_TYPE_ARRAY:
case DT_TYPE_REFERENCE: case DT_TYPE_REFERENCE:
case DT_TYPE_RVALUEREF:
return IT_POINTER; return IT_POINTER;
} }
} }
InterCodeGenerator::ExValue InterCodeGenerator::ToValue(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v) InterCodeGenerator::ExValue InterCodeGenerator::ToValue(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v)
{ {
if (v.mType && v.mType->mType == DT_TYPE_REFERENCE) if (v.mType && v.mType->IsReference())
{ {
v.mType = v.mType->mBase; v.mType = v.mType->mBase;
v.mReference++; v.mReference++;
@ -81,9 +82,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* p
{ {
int stemp = v.mTemp; int stemp = v.mTemp;
if (type->mType == DT_TYPE_REFERENCE) if (type->IsReference())
{ {
if (v.mType->mType == DT_TYPE_REFERENCE) if (v.mType->IsReference())
{ {
if (!type->mBase->IsSubType(v.mType->mBase)) if (!type->mBase->IsSubType(v.mType->mBase))
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_TYPES, "Incompatible type for reference"); mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_TYPES, "Incompatible type for reference");
@ -960,7 +961,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
vdec->mVarIndex = nindex; vdec->mVarIndex = nindex;
vdec->mBase = pdec->mBase; vdec->mBase = pdec->mBase;
if (pdec->mBase->mType == DT_TYPE_ARRAY || pdec->mBase->mType == DT_TYPE_REFERENCE) if (pdec->mBase->mType == DT_TYPE_ARRAY || pdec->mBase->mType == DT_TYPE_REFERENCE || pdec->mBase->mType == DT_TYPE_RVALUEREF)
ains->mConst.mOperandSize = 2; ains->mConst.mOperandSize = 2;
else else
ains->mConst.mOperandSize = pdec->mSize; ains->mConst.mOperandSize = pdec->mSize;
@ -992,7 +993,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
vr = TranslateExpression(procType, proc, block, texp, destack, breakBlock, continueBlock, inlineMapper, &vp); vr = TranslateExpression(procType, proc, block, texp, destack, breakBlock, continueBlock, inlineMapper, &vp);
if (!(pdec && pdec->mBase->mType == DT_TYPE_REFERENCE) && (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION)) if (!(pdec && pdec->mBase->IsReference()) && (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION))
{ {
if (pdec && !pdec->mBase->CanAssign(vr.mType)) if (pdec && !pdec->mBase->CanAssign(vr.mType))
mErrors->Error(texp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types"); mErrors->Error(texp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types");
@ -1026,7 +1027,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
{ {
if (vr.mType->mType == DT_TYPE_ARRAY || vr.mType->mType == DT_TYPE_FUNCTION) if (vr.mType->mType == DT_TYPE_ARRAY || vr.mType->mType == DT_TYPE_FUNCTION)
vr = Dereference(proc, texp, block, vr, 1); vr = Dereference(proc, texp, block, vr, 1);
else if (pdec && (pdec->mBase->mType == DT_TYPE_REFERENCE && vr.mType->mType != DT_TYPE_REFERENCE)) else if (pdec && (pdec->mBase->IsReference() && !vr.mType->IsReference()))
vr = Dereference(proc, texp, block, vr, 1); vr = Dereference(proc, texp, block, vr, 1);
else else
vr = Dereference(proc, texp, block, vr); vr = Dereference(proc, texp, block, vr);
@ -1054,7 +1055,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
wins->mSrc[1].mTemp = ains->mDst.mTemp; wins->mSrc[1].mTemp = ains->mDst.mTemp;
if (pdec) if (pdec)
{ {
if (pdec->mBase->mType == DT_TYPE_ARRAY || pdec->mBase->mType == DT_TYPE_REFERENCE) if (pdec->mBase->mType == DT_TYPE_ARRAY || pdec->mBase->mType == DT_TYPE_REFERENCE || pdec->mBase->mType == DT_TYPE_RVALUEREF)
wins->mSrc[1].mOperandSize = 2; wins->mSrc[1].mOperandSize = 2;
else else
wins->mSrc[1].mOperandSize = pdec->mSize; wins->mSrc[1].mOperandSize = pdec->mSize;
@ -1124,7 +1125,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
block->Append(ins); block->Append(ins);
ExValue rv(rdec->mBase, ins->mDst.mTemp, 1); ExValue rv(rdec->mBase, ins->mDst.mTemp, 1);
if (rdec->mBase->mType != DT_TYPE_REFERENCE) if (!rdec->mBase->IsReference())
rv = Dereference(proc, exp, block, rv); rv = Dereference(proc, exp, block, rv);
return rv; return rv;
} }
@ -1728,7 +1729,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (!(dec->mBase->mFlags & DTF_DEFINED)) if (!(dec->mBase->mFlags & DTF_DEFINED))
mErrors->Error(dec->mLocation, EERR_VARIABLE_TYPE, "Undefined variable type"); mErrors->Error(dec->mLocation, EERR_VARIABLE_TYPE, "Undefined variable type");
if (exp->mDecType->mType == DT_TYPE_REFERENCE) if (exp->mDecType->IsReference())
return ExValue(exp->mDecType->mBase, ins->mDst.mTemp, ref + 1); return ExValue(exp->mDecType->mBase, ins->mDst.mTemp, ref + 1);
else else
return ExValue(exp->mDecType, ins->mDst.mTemp, ref); return ExValue(exp->mDecType, ins->mDst.mTemp, ref);
@ -1743,7 +1744,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
vr = TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper, &vl); vr = TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper, &vl);
} }
else if (exp->mType == EX_INITIALIZATION && exp->mLeft->mDecType && exp->mLeft->mDecType->mType == DT_TYPE_REFERENCE) else if (exp->mType == EX_INITIALIZATION && exp->mLeft->mDecType && exp->mLeft->mDecType->IsReference())
{ {
vr = TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper); vr = TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper);
vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
@ -1776,7 +1777,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
} }
if (vl.mType->mType == DT_TYPE_REFERENCE) if (vl.mType->IsReference())
{ {
vr = Dereference(proc, exp, block, vr, 1); vr = Dereference(proc, exp, block, vr, 1);
vl = Dereference(proc, exp, block, vl, 2); vl = Dereference(proc, exp, block, vl, 2);
@ -3172,7 +3173,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
ExValue vp(ptype ? ptype : TheSignedIntTypeDeclaration, ains->mDst.mTemp, 1); ExValue vp(ptype ? ptype : TheSignedIntTypeDeclaration, ains->mDst.mTemp, 1);
if (pdec && pdec->mBase->mType == DT_TYPE_REFERENCE && texp->mType == EX_CALL && texp->mDecType->mType != DT_TYPE_REFERENCE) if (pdec && pdec->mBase->IsReference() && texp->mType == EX_CALL && !texp->mDecType->IsReference())
{ {
mErrors->Error(texp->mLocation, EERR_MISSING_TEMP, "Missing temporary variable"); mErrors->Error(texp->mLocation, EERR_MISSING_TEMP, "Missing temporary variable");
#if 0 #if 0
@ -3202,7 +3203,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
else else
vr = TranslateExpression(procType, proc, block, texp, destack, breakBlock, continueBlock, inlineMapper, nullptr); vr = TranslateExpression(procType, proc, block, texp, destack, breakBlock, continueBlock, inlineMapper, nullptr);
if (!(pdec && pdec->mBase->mType == DT_TYPE_REFERENCE) && (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION)) if (!(pdec && pdec->mBase->IsReference()) && (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION))
{ {
if (pdec && !pdec->mBase->CanAssign(vr.mType)) if (pdec && !pdec->mBase->CanAssign(vr.mType))
mErrors->Error(texp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types"); mErrors->Error(texp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types");
@ -3244,7 +3245,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
mErrors->Error(texp->mLocation, EWARN_NUMERIC_0_USED_AS_NULLPTR, "Numeric 0 used for nullptr"); mErrors->Error(texp->mLocation, EWARN_NUMERIC_0_USED_AS_NULLPTR, "Numeric 0 used for nullptr");
vr = CoerceType(proc, texp, block, vr, pdec->mBase); vr = CoerceType(proc, texp, block, vr, pdec->mBase);
} }
else if (pdec && (pdec->mBase->mType == DT_TYPE_REFERENCE && vr.mType->mType != DT_TYPE_REFERENCE)) else if (pdec && (pdec->mBase->IsReference() && !vr.mType->IsReference()))
vr = Dereference(proc, texp, block, vr, 1); vr = Dereference(proc, texp, block, vr, 1);
else else
vr = Dereference(proc, texp, block, vr); vr = Dereference(proc, texp, block, vr);
@ -3272,7 +3273,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
wins->mSrc[1].mTemp = ains->mDst.mTemp; wins->mSrc[1].mTemp = ains->mDst.mTemp;
if (pdec) if (pdec)
{ {
if (pdec->mBase->mType == DT_TYPE_ARRAY || pdec->mBase->mType == DT_TYPE_REFERENCE) if (pdec->mBase->mType == DT_TYPE_ARRAY || pdec->mBase->mType == DT_TYPE_REFERENCE || pdec->mBase->mType == DT_TYPE_RVALUEREF)
{ {
wins->mSrc[1].mOperandSize = 2; wins->mSrc[1].mOperandSize = 2;
wins->mSrc[0].mType = IT_POINTER; wins->mSrc[0].mType = IT_POINTER;
@ -3359,7 +3360,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
return ExValue(ftype->mBase, vins->mDst.mTemp, 1); return ExValue(ftype->mBase, vins->mDst.mTemp, 1);
} }
else if (ftype->mBase->mType == DT_TYPE_REFERENCE) else if (ftype->mBase->IsReference())
return ExValue(ftype->mBase->mBase, cins->mDst.mTemp, 1); return ExValue(ftype->mBase->mBase, cins->mDst.mTemp, 1);
else else
return ExValue(ftype->mBase, cins->mDst.mTemp); return ExValue(ftype->mBase, cins->mDst.mTemp);
@ -3468,7 +3469,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
InterInstruction * ins = new InterInstruction(exp->mLocation, IC_RETURN); InterInstruction * ins = new InterInstruction(exp->mLocation, IC_RETURN);
if (exp->mLeft) if (exp->mLeft)
{ {
if (procType->mBase->mType == DT_TYPE_REFERENCE) if (procType->mBase->IsReference())
{ {
vr = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); vr = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
@ -4128,6 +4129,14 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
else if (exp->mDecType->mType == DT_TYPE_VOID) else if (exp->mDecType->mType == DT_TYPE_VOID)
{ {
} }
else if (exp->mDecType->IsReference() && exp->mDecType->mBase->IsConstSame(vr.mType))
{
if (vr.mReference == 0)
mErrors->Error(exp->mLocation, EERR_NOT_AN_LVALUE, "Not an L value");
vr = Dereference(proc, exp, block, vr, 1);
return ExValue(exp->mDecType, vr.mTemp);
}
else else
{ {
vr = Dereference(proc, exp, block, vr); vr = Dereference(proc, exp, block, vr);

View File

@ -2035,7 +2035,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
adec->mOffset = 0; adec->mOffset = 0;
adec->mBase = new Declaration(mScanner->mLocation, DT_TYPE_REFERENCE); adec->mBase = new Declaration(mScanner->mLocation, DT_TYPE_REFERENCE);
adec->mBase->mSize = 2; adec->mBase->mSize = 2;
adec->mBase->mBase = pthis->mBase; adec->mBase->mBase = pthis->mBase->ToConstType();
adec->mBase->mFlags |= DTF_CONST | DTF_DEFINED; adec->mBase->mFlags |= DTF_CONST | DTF_DEFINED;
adec->mSize = adec->mBase->mSize; adec->mSize = adec->mBase->mSize;
adec->mIdent = adec->mQualIdent = Ident::Unique("_"); adec->mIdent = adec->mQualIdent = Ident::Unique("_");
@ -4733,7 +4733,10 @@ Expression* Parser::ParseQualify(Expression* exp)
{ {
if (mflags & DTF_PROTECTED) if (mflags & DTF_PROTECTED)
{ {
if (!mThisPointer || mThisPointer->mBase->IsConstSame(dtype)) Declaration* tp = mThisPointer;
if (tp && tp->mType == DT_ARGUMENT)
tp = tp->mBase;
if (!(tp && tp->mBase->IsConstSame(dtype)))
mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Struct member identifier not visible", ident); mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Struct member identifier not visible", ident);
} }
@ -4952,6 +4955,13 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
dist += 512; dist += 512;
else if (ptype->mType == DT_TYPE_REFERENCE && ptype->mBase->mType == DT_TYPE_STRUCT && etype->mType == DT_TYPE_STRUCT) else if (ptype->mType == DT_TYPE_REFERENCE && ptype->mBase->mType == DT_TYPE_STRUCT && etype->mType == DT_TYPE_STRUCT)
{ {
if (ex->IsLValue())
dist += 2;
else if (ptype->mBase->mFlags & DTF_CONST)
dist += 4;
else
return NOOVERLOAD;
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))
@ -7379,6 +7389,8 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
if (!(mdec->mFlags & DTF_DEFINED)) if (!(mdec->mFlags & DTF_DEFINED))
{ {
Declaration* mpdec = mScope->Lookup(tmpld->mScope->Mangle(mdec->mIdent)); Declaration* mpdec = mScope->Lookup(tmpld->mScope->Mangle(mdec->mIdent));
while (mpdec && !mdec->mBase->IsTemplateSameParams(mpdec->mBase, tdec))
mpdec = mpdec->mNext;
if (mpdec && mpdec->mTemplate) if (mpdec && mpdec->mTemplate)
{ {
p->ParseTemplateExpansion(mpdec->mTemplate, tdec); p->ParseTemplateExpansion(mpdec->mTemplate, tdec);
@ -7411,6 +7423,8 @@ void Parser::CompleteTemplateExpansion(Declaration* tmpld)
while (mdec) while (mdec)
{ {
Declaration* mpdec = mScope->Lookup(mdec->mQualIdent); Declaration* mpdec = mScope->Lookup(mdec->mQualIdent);
while (mpdec && !mpdec->IsSameParams(mdec->mParams))
mpdec = mpdec->mNext;
if (mpdec && mpdec->mType == DT_TEMPLATE) if (mpdec && mpdec->mType == DT_TEMPLATE)
{ {
ParseTemplateExpansion(mpdec, tmpld); ParseTemplateExpansion(mpdec, tmpld);
@ -7561,7 +7575,13 @@ void Parser::ParseTemplateDeclaration(void)
tdec->mQualIdent = tdec->mBase->mQualIdent; tdec->mQualIdent = tdec->mBase->mQualIdent;
tdec->mScope->mName = tdec->mQualIdent; tdec->mScope->mName = tdec->mQualIdent;
mScope->Insert(tdec->mQualIdent, tdec->mBase); Declaration * pdec = mScope->Insert(tdec->mQualIdent, tdec->mBase);
if (pdec)
{
tdec->mBase->mNext = pdec->mNext;
pdec->mNext = tdec->mBase;
}
mCompilationUnits->mScope->Insert(tdec->mQualIdent, tdec->mBase); mCompilationUnits->mScope->Insert(tdec->mQualIdent, tdec->mBase);
} }