Add iterators to string
This commit is contained in:
parent
e084035a71
commit
33d692194a
|
@ -1,4 +1,5 @@
|
||||||
#include "ctype.h"
|
#include "ctype.h"
|
||||||
|
#include "conio.h"
|
||||||
|
|
||||||
#define CC_CTRL 0x00
|
#define CC_CTRL 0x00
|
||||||
#define CC_BREAK 0x01
|
#define CC_BREAK 0x01
|
||||||
|
@ -86,3 +87,19 @@ bool isxdigit(char c)
|
||||||
{
|
{
|
||||||
return (c < 128) && (_cinfo[c] & CC_HEX);
|
return (c < 128) && (_cinfo[c] & CC_HEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char tolower(char c)
|
||||||
|
{
|
||||||
|
if (c >= 'A' && c <= 'Z')
|
||||||
|
return c + ('a' - 'A');
|
||||||
|
else
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
char toupper(char c)
|
||||||
|
{
|
||||||
|
if (c >= 'a' && c <= 'z')
|
||||||
|
return c + ('A' - 'a');
|
||||||
|
else
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,9 @@ inline bool isdigit(char c);
|
||||||
|
|
||||||
inline bool isxdigit(char c);
|
inline bool isxdigit(char c);
|
||||||
|
|
||||||
|
char tolower(char c);
|
||||||
|
|
||||||
|
char toupper(char c);
|
||||||
|
|
||||||
#pragma compile("ctype.c")
|
#pragma compile("ctype.c")
|
||||||
|
|
||||||
|
|
|
@ -965,6 +965,19 @@ istream & istream::operator>>(char * p)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
istream & istream::operator>>(string & s)
|
||||||
|
{
|
||||||
|
doskipws();
|
||||||
|
s.clear();
|
||||||
|
char c = get();
|
||||||
|
while (c > ' ')
|
||||||
|
{
|
||||||
|
s += c;
|
||||||
|
c = get();
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
cistream::cistream(void)
|
cistream::cistream(void)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,7 @@ public:
|
||||||
istream & operator>>(float & val);
|
istream & operator>>(float & val);
|
||||||
|
|
||||||
istream & operator>>(char * p);
|
istream & operator>>(char * p);
|
||||||
|
istream & operator>>(string & s);
|
||||||
|
|
||||||
istream(void);
|
istream(void);
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -94,6 +94,12 @@ string::~string(void)
|
||||||
{
|
{
|
||||||
free(cstr);
|
free(cstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void string::clear(void)
|
||||||
|
{
|
||||||
|
free(cstr);
|
||||||
|
cstr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void string::copyseg(char * p, char at, char num) const
|
void string::copyseg(char * p, char at, char num) const
|
||||||
{
|
{
|
||||||
|
@ -476,6 +482,37 @@ inline char string::operator[](char t) const
|
||||||
return cstr[t + 1];
|
return cstr[t + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char * string::begin(void)
|
||||||
|
{
|
||||||
|
return cstr ? cstr + 1 : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * string::begin(void) const
|
||||||
|
{
|
||||||
|
return cstr ? cstr + 1 : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * string::cbegin(void) const
|
||||||
|
{
|
||||||
|
return cstr ? cstr + 1 : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * string::end(void)
|
||||||
|
{
|
||||||
|
return cstr ? cstr + 1 + cstr[0] : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * string::end(void) const
|
||||||
|
{
|
||||||
|
return cstr ? cstr + 1 + cstr[0] : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * string::cend(void) const
|
||||||
|
{
|
||||||
|
return cstr ? cstr + 1 + cstr[0] : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
string string::substr(char pos, char len) const
|
string string::substr(char pos, char len) const
|
||||||
{
|
{
|
||||||
if (!cstr || len == 0 || pos >= cstr[0])
|
if (!cstr || len == 0 || pos >= cstr[0])
|
||||||
|
|
|
@ -21,6 +21,8 @@ public:
|
||||||
|
|
||||||
unsigned size(void) const;
|
unsigned size(void) const;
|
||||||
|
|
||||||
|
void clear(void);
|
||||||
|
|
||||||
string & operator=(const string & s);
|
string & operator=(const string & s);
|
||||||
string & operator=(string && s);
|
string & operator=(string && s);
|
||||||
string & operator=(const char * s);
|
string & operator=(const char * s);
|
||||||
|
@ -57,6 +59,14 @@ public:
|
||||||
char & operator[](char t);
|
char & operator[](char t);
|
||||||
char operator[](char t) const;
|
char operator[](char t) const;
|
||||||
|
|
||||||
|
char * begin(void);
|
||||||
|
const char * begin(void) const;
|
||||||
|
const char * cbegin(void) const;
|
||||||
|
|
||||||
|
char * end(void);
|
||||||
|
const char * end(void) const;
|
||||||
|
const char * cend(void) const;
|
||||||
|
|
||||||
const char * tocstr(void) const;
|
const char * tocstr(void) const;
|
||||||
|
|
||||||
string substr(char pos, char len) const;
|
string substr(char pos, char len) const;
|
||||||
|
|
|
@ -1501,7 +1501,7 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
|
||||||
}
|
}
|
||||||
else if (tdec->mType == DT_TYPE_POINTER)
|
else if (tdec->mType == DT_TYPE_POINTER)
|
||||||
{
|
{
|
||||||
if (fdec->mType == DT_TYPE_POINTER)
|
if (fdec->mType == DT_TYPE_POINTER || fdec->mType == DT_TYPE_ARRAY)
|
||||||
return ResolveTemplate(fdec->mBase, tdec->mBase);
|
return ResolveTemplate(fdec->mBase, tdec->mBase);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
@ -1510,6 +1510,8 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
|
||||||
{
|
{
|
||||||
if (fdec->mType == DT_TYPE_ARRAY)
|
if (fdec->mType == DT_TYPE_ARRAY)
|
||||||
fdec = fdec->mBase->BuildPointer(fdec->mLocation);
|
fdec = fdec->mBase->BuildPointer(fdec->mLocation);
|
||||||
|
else if (fdec->mType == DT_TYPE_FUNCTION)
|
||||||
|
fdec = fdec->BuildPointer(fdec->mLocation);
|
||||||
|
|
||||||
Declaration* pdec;
|
Declaration* pdec;
|
||||||
if (tdec->mBase)
|
if (tdec->mBase)
|
||||||
|
@ -1816,6 +1818,9 @@ bool Declaration::IsSubType(const Declaration* dec) const
|
||||||
if (this == dec)
|
if (this == dec)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (mType == DT_TYPE_VOID)
|
||||||
|
return true;
|
||||||
|
|
||||||
if (IsReference() && dec->IsReference())
|
if (IsReference() && dec->IsReference())
|
||||||
return mBase->IsSubType(dec->mBase);
|
return mBase->IsSubType(dec->mBase);
|
||||||
|
|
||||||
|
@ -1996,8 +2001,10 @@ bool Declaration::IsTemplateSameParams(const Declaration* dec, const Declaration
|
||||||
{
|
{
|
||||||
if (mType == DT_TYPE_FUNCTION && dec->mType == DT_TYPE_FUNCTION)
|
if (mType == DT_TYPE_FUNCTION && dec->mType == DT_TYPE_FUNCTION)
|
||||||
{
|
{
|
||||||
// Skip this pointer for now
|
Declaration* ld = mParams, * rd = dec->mParams;
|
||||||
Declaration* ld = mParams->mNext, * rd = dec->mParams;
|
if (mFlags & DTF_FUNC_THIS)
|
||||||
|
ld = ld->mNext;
|
||||||
|
|
||||||
while (ld && rd)
|
while (ld && rd)
|
||||||
{
|
{
|
||||||
if (!ld->mBase->IsTemplateSame(rd->mBase, tdec))
|
if (!ld->mBase->IsTemplateSame(rd->mBase, tdec))
|
||||||
|
@ -2112,7 +2119,7 @@ bool Declaration::IsSame(const Declaration* dec) const
|
||||||
return mInteger == dec->mInteger;
|
return mInteger == dec->mInteger;
|
||||||
else if (mType == DT_TYPE_INTEGER)
|
else if (mType == DT_TYPE_INTEGER)
|
||||||
return true;
|
return true;
|
||||||
else if (mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_VOID)
|
else if (mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_VOID || mType == DT_TYPE_AUTO)
|
||||||
return true;
|
return true;
|
||||||
else if (mType == DT_TYPE_ENUM)
|
else if (mType == DT_TYPE_ENUM)
|
||||||
return mIdent == dec->mIdent;
|
return mIdent == dec->mIdent;
|
||||||
|
|
|
@ -3539,6 +3539,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
{
|
{
|
||||||
vr.mReference++;
|
vr.mReference++;
|
||||||
vr = Dereference(proc, texp, block, vr);
|
vr = Dereference(proc, texp, block, vr);
|
||||||
|
vr.mType = vr.mType->mBase;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
vr = Dereference(proc, texp, block, vr);
|
vr = Dereference(proc, texp, block, vr);
|
||||||
|
|
|
@ -25968,7 +25968,7 @@ bool NativeCodeBasicBlock::Check16BitSum(int at, NativeRegisterSum16Info& info)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::IsFinalZeroPageUse(const NativeCodeBasicBlock* block, int at, int from, int to, bool pair)
|
bool NativeCodeBasicBlock::IsFinalZeroPageUse(const NativeCodeBasicBlock* block, int at, int from, int to, bool pair, bool fchanged)
|
||||||
{
|
{
|
||||||
if (at == 0 && mVisited)
|
if (at == 0 && mVisited)
|
||||||
return false;
|
return false;
|
||||||
|
@ -25977,70 +25977,80 @@ bool NativeCodeBasicBlock::IsFinalZeroPageUse(const NativeCodeBasicBlock* block,
|
||||||
{
|
{
|
||||||
mPatched = true;
|
mPatched = true;
|
||||||
|
|
||||||
if (at == 0)
|
if (at != 0 || (mEntryRequiredRegs[from] || mEntryRequiredRegs[to] || (pair && (mEntryRequiredRegs[from + 1] || mEntryRequiredRegs[to + 1]))))
|
||||||
{
|
{
|
||||||
mPatched = true;
|
if (at == 0)
|
||||||
|
{
|
||||||
|
mPatched = true;
|
||||||
|
|
||||||
if (mNumEntries > 1)
|
if (mNumEntries > 1)
|
||||||
{
|
|
||||||
for (int i = 0; i < mEntryBlocks.Size(); i++)
|
|
||||||
if (!mEntryBlocks[i]->IsDominatedBy(block))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (at < mIns.Size())
|
|
||||||
{
|
|
||||||
if (mIns[at].mMode == ASMIM_ZERO_PAGE)
|
|
||||||
{
|
|
||||||
if (mIns[at].mAddress == to)
|
|
||||||
return false;
|
|
||||||
if (pair && mIns[at].mAddress == to + 1)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (mIns[at].mMode == ASMIM_INDIRECT_Y)
|
|
||||||
{
|
|
||||||
if (mIns[at].mAddress == to)
|
|
||||||
return false;
|
|
||||||
if (mIns[at].mAddress + 1 == to)
|
|
||||||
return false;
|
|
||||||
if (pair && mIns[at].mAddress == to + 1)
|
|
||||||
return false;
|
|
||||||
if (!pair && mIns[at].mAddress == from)
|
|
||||||
return false;
|
|
||||||
if (mIns[at].mAddress + 1 == from)
|
|
||||||
return false;
|
|
||||||
if (pair && mIns[at].mAddress == from + 1)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (mIns[at].mType == ASMIT_JSR)
|
|
||||||
{
|
|
||||||
LinkerObject* lo = mIns[at].mLinkerObject;
|
|
||||||
if (lo)
|
|
||||||
{
|
{
|
||||||
for (int i = 0; i < lo->mNumTemporaries; i++)
|
fchanged = true;
|
||||||
|
for (int i = 0; i < mEntryBlocks.Size(); i++)
|
||||||
|
if (mEntryBlocks[i] != block && !mEntryBlocks[i]->IsDominatedBy(block))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (at < mIns.Size())
|
||||||
|
{
|
||||||
|
if (mIns[at].mMode == ASMIM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
if (mIns[at].mAddress == to && (fchanged || mIns[at].ChangesAddress()))
|
||||||
|
return false;
|
||||||
|
if (pair && mIns[at].mAddress == to + 1 && (fchanged || mIns[at].ChangesAddress()))
|
||||||
|
return false;
|
||||||
|
if (mIns[at].mAddress == from && mIns[at].ChangesAddress())
|
||||||
|
fchanged = true;
|
||||||
|
if (pair && mIns[at].mAddress == from + 1 && mIns[at].ChangesAddress())
|
||||||
|
fchanged = true;
|
||||||
|
}
|
||||||
|
else if (mIns[at].mMode == ASMIM_INDIRECT_Y)
|
||||||
|
{
|
||||||
|
if (mIns[at].mAddress == to)
|
||||||
|
return false;
|
||||||
|
if (mIns[at].mAddress + 1 == to)
|
||||||
|
return false;
|
||||||
|
if (pair && mIns[at].mAddress == to + 1)
|
||||||
|
return false;
|
||||||
|
if (!pair && mIns[at].mAddress == from)
|
||||||
|
return false;
|
||||||
|
if (mIns[at].mAddress + 1 == from)
|
||||||
|
return false;
|
||||||
|
if (pair && mIns[at].mAddress == from + 1)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (mIns[at].mType == ASMIT_JSR)
|
||||||
|
{
|
||||||
|
fchanged = true;
|
||||||
|
|
||||||
|
LinkerObject* lo = mIns[at].mLinkerObject;
|
||||||
|
if (lo)
|
||||||
{
|
{
|
||||||
if (from >= lo->mTemporaries[i] && from < lo->mTemporaries[i] + lo->mTempSizes[i] ||
|
for (int i = 0; i < lo->mNumTemporaries; i++)
|
||||||
to >= lo->mTemporaries[i] && to < lo->mTemporaries[i] + lo->mTempSizes[i])
|
{
|
||||||
|
if (from >= lo->mTemporaries[i] && from < lo->mTemporaries[i] + lo->mTempSizes[i] ||
|
||||||
|
to >= lo->mTemporaries[i] && to < lo->mTemporaries[i] + lo->mTempSizes[i])
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mIns[at].mFlags & NCIF_USE_ZP_32_X)
|
||||||
|
{
|
||||||
|
if (to >= mIns[at].mParam && to < mIns[at].mParam + 4 ||
|
||||||
|
from >= mIns[at].mParam && from < mIns[at].mParam + 4)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mIns[at].mFlags & NCIF_USE_ZP_32_X)
|
at++;
|
||||||
{
|
|
||||||
if (to >= mIns[at].mParam && to < mIns[at].mParam + 4 ||
|
|
||||||
from >= mIns[at].mParam && from < mIns[at].mParam + 4)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
at++;
|
if (mTrueJump && !mTrueJump->IsFinalZeroPageUse(block, 0, from, to, pair, fchanged))
|
||||||
|
return false;
|
||||||
|
if (mFalseJump && !mFalseJump->IsFinalZeroPageUse(block, 0, from, to, pair, fchanged))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTrueJump && !mTrueJump->IsFinalZeroPageUse(block, 0, from, to, pair))
|
|
||||||
return false;
|
|
||||||
if (mFalseJump && !mFalseJump->IsFinalZeroPageUse(block, 0, from, to, pair))
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -26065,7 +26075,7 @@ bool NativeCodeBasicBlock::ReplaceFinalZeroPageUse(NativeCodeProcedure* nproc)
|
||||||
mIns[i + 1].mAddress >= BC_REG_TMP)
|
mIns[i + 1].mAddress >= BC_REG_TMP)
|
||||||
{
|
{
|
||||||
nproc->ResetPatched();
|
nproc->ResetPatched();
|
||||||
if (IsFinalZeroPageUse(this, i + 2, mIns[i + 1].mAddress, mIns[i + 0].mAddress, false))
|
if (IsFinalZeroPageUse(this, i + 2, mIns[i + 1].mAddress, mIns[i + 0].mAddress, false, false))
|
||||||
{
|
{
|
||||||
nproc->ResetPatched();
|
nproc->ResetPatched();
|
||||||
if (ForwardReplaceZeroPage(i + 2, mIns[i + 1].mAddress, mIns[i + 0].mAddress))
|
if (ForwardReplaceZeroPage(i + 2, mIns[i + 1].mAddress, mIns[i + 0].mAddress))
|
||||||
|
@ -26084,7 +26094,7 @@ bool NativeCodeBasicBlock::ReplaceFinalZeroPageUse(NativeCodeProcedure* nproc)
|
||||||
mIns[i + 1].mAddress >= BC_REG_TMP)
|
mIns[i + 1].mAddress >= BC_REG_TMP)
|
||||||
{
|
{
|
||||||
nproc->ResetPatched();
|
nproc->ResetPatched();
|
||||||
if (IsFinalZeroPageUse(this, i + 4, mIns[i + 1].mAddress, mIns[i + 0].mAddress, true))
|
if (IsFinalZeroPageUse(this, i + 4, mIns[i + 1].mAddress, mIns[i + 0].mAddress, true, false))
|
||||||
{
|
{
|
||||||
nproc->ResetPatched();
|
nproc->ResetPatched();
|
||||||
if (ForwardReplaceZeroPage(i + 4, mIns[i + 1].mAddress, mIns[i + 0].mAddress))
|
if (ForwardReplaceZeroPage(i + 4, mIns[i + 1].mAddress, mIns[i + 0].mAddress))
|
||||||
|
@ -26110,7 +26120,7 @@ bool NativeCodeBasicBlock::ReplaceFinalZeroPageUse(NativeCodeProcedure* nproc)
|
||||||
mIns[i + 2].mAddress >= BC_REG_TMP)
|
mIns[i + 2].mAddress >= BC_REG_TMP)
|
||||||
{
|
{
|
||||||
nproc->ResetPatched();
|
nproc->ResetPatched();
|
||||||
if (IsFinalZeroPageUse(this, i + 6, mIns[i + 2].mAddress, mIns[i + 0].mAddress, true))
|
if (IsFinalZeroPageUse(this, i + 6, mIns[i + 2].mAddress, mIns[i + 0].mAddress, true, false))
|
||||||
{
|
{
|
||||||
nproc->ResetPatched();
|
nproc->ResetPatched();
|
||||||
if (ForwardReplaceZeroPage(i + 6, mIns[i + 2].mAddress, mIns[i + 0].mAddress))
|
if (ForwardReplaceZeroPage(i + 6, mIns[i + 2].mAddress, mIns[i + 0].mAddress))
|
||||||
|
@ -26135,7 +26145,7 @@ bool NativeCodeBasicBlock::ReplaceFinalZeroPageUse(NativeCodeProcedure* nproc)
|
||||||
mIns[i + 1].mAddress >= BC_REG_TMP)
|
mIns[i + 1].mAddress >= BC_REG_TMP)
|
||||||
{
|
{
|
||||||
nproc->ResetPatched();
|
nproc->ResetPatched();
|
||||||
if (IsFinalZeroPageUse(this, i + 5, mIns[i + 1].mAddress, mIns[i + 0].mAddress, true))
|
if (IsFinalZeroPageUse(this, i + 5, mIns[i + 1].mAddress, mIns[i + 0].mAddress, true, false))
|
||||||
{
|
{
|
||||||
nproc->ResetPatched();
|
nproc->ResetPatched();
|
||||||
if (ForwardReplaceZeroPage(i + 5, mIns[i + 1].mAddress, mIns[i + 0].mAddress))
|
if (ForwardReplaceZeroPage(i + 5, mIns[i + 1].mAddress, mIns[i + 0].mAddress))
|
||||||
|
@ -41341,7 +41351,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
{
|
{
|
||||||
mInterProc = proc;
|
mInterProc = proc;
|
||||||
|
|
||||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "dungeon_rand_path");
|
CheckFunc = !strcmp(mInterProc->mIdent->mString, "mod<struct lambda#0>");
|
||||||
|
|
||||||
int nblocks = proc->mBlocks.Size();
|
int nblocks = proc->mBlocks.Size();
|
||||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||||
|
@ -42025,6 +42035,7 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
#if 1
|
#if 1
|
||||||
if (step == 2)
|
if (step == 2)
|
||||||
{
|
{
|
||||||
|
BuildDataFlowSets();
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->ReplaceFinalZeroPageUse(this);
|
mEntryBlock->ReplaceFinalZeroPageUse(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -543,7 +543,7 @@ public:
|
||||||
bool Check16BitSum(const NativeCodeBasicBlock* block, int origin, int at, int reg);
|
bool Check16BitSum(const NativeCodeBasicBlock* block, int origin, int at, int reg);
|
||||||
bool EliminateUpper16BitSum(NativeCodeProcedure* nproc);
|
bool EliminateUpper16BitSum(NativeCodeProcedure* nproc);
|
||||||
|
|
||||||
bool IsFinalZeroPageUse(const NativeCodeBasicBlock* block, int at, int from, int to, bool pair);
|
bool IsFinalZeroPageUse(const NativeCodeBasicBlock* block, int at, int from, int to, bool pair, bool fchanged);
|
||||||
bool ReplaceFinalZeroPageUse(NativeCodeProcedure* nproc);
|
bool ReplaceFinalZeroPageUse(NativeCodeProcedure* nproc);
|
||||||
bool ForwardReplaceZeroPage(int at, int from, int to);
|
bool ForwardReplaceZeroPage(int at, int from, int to);
|
||||||
|
|
||||||
|
|
|
@ -297,7 +297,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
|
||||||
mdec->mType = DT_CONST_FUNCTION;
|
mdec->mType = DT_CONST_FUNCTION;
|
||||||
mdec->mSection = mCodeSection;
|
mdec->mSection = mCodeSection;
|
||||||
mdec->mFlags |= DTF_GLOBAL;
|
mdec->mFlags |= DTF_GLOBAL;
|
||||||
mdec->mBase->mFlags |= DTF_FUNC_THIS;
|
// mdec->mBase->mFlags |= DTF_FUNC_THIS;
|
||||||
|
|
||||||
if (mCompilerOptions & COPT_NATIVE)
|
if (mCompilerOptions & COPT_NATIVE)
|
||||||
mdec->mFlags |= DTF_NATIVE;
|
mdec->mFlags |= DTF_NATIVE;
|
||||||
|
@ -627,7 +627,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
|
||||||
|
|
||||||
Declaration* Parser::ParseBaseTypeQualify(bool qualified, Declaration* dec, const Ident*& pident)
|
Declaration* Parser::ParseBaseTypeQualify(bool qualified, Declaration* dec, const Ident*& pident)
|
||||||
{
|
{
|
||||||
while (dec && (dec->mType == DT_NAMESPACE || (qualified && (dec->mType == DT_TYPE_STRUCT || dec->mType == DT_TYPE_TEMPLATE))) && ConsumeTokenIf(TK_COLCOLON))
|
while (dec && (dec->mType == DT_NAMESPACE || (qualified && (dec->mType == DT_TYPE_STRUCT || dec->mType == DT_TYPE_TEMPLATE)) && !dec->mTemplate) && ConsumeTokenIf(TK_COLCOLON))
|
||||||
{
|
{
|
||||||
if (ExpectToken(TK_IDENT))
|
if (ExpectToken(TK_IDENT))
|
||||||
{
|
{
|
||||||
|
@ -3168,7 +3168,7 @@ void Parser::PrependThisArgument(Declaration* fdec, Declaration* pthis)
|
||||||
}
|
}
|
||||||
|
|
||||||
fdec->mParams = adec;
|
fdec->mParams = adec;
|
||||||
|
fdec->mClass = pthis;
|
||||||
fdec->mFlags |= DTF_FUNC_THIS;
|
fdec->mFlags |= DTF_FUNC_THIS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4161,12 +4161,15 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
||||||
|
|
||||||
if (ndec->mBase->mType == DT_TYPE_FUNCTION)
|
if (ndec->mBase->mType == DT_TYPE_FUNCTION)
|
||||||
{
|
{
|
||||||
if (pthis)
|
ndec->mBase->mClass = pthis;
|
||||||
|
|
||||||
|
if (pthis && !(storageFlags & DTF_STATIC))
|
||||||
{
|
{
|
||||||
if (ConsumeTokenIf(TK_CONST))
|
if (ConsumeTokenIf(TK_CONST))
|
||||||
PrependThisArgument(ndec->mBase, pthis->mBase->ToConstType()->BuildConstPointer(ndec->mLocation));
|
PrependThisArgument(ndec->mBase, pthis->mBase->ToConstType()->BuildConstPointer(ndec->mLocation));
|
||||||
else
|
else
|
||||||
PrependThisArgument(ndec->mBase, pthis);
|
PrependThisArgument(ndec->mBase, pthis);
|
||||||
|
ndec->mBase->mFlags |= DTF_FUNC_THIS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4236,30 +4239,41 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
||||||
{
|
{
|
||||||
if (pdec->mBase->mFlags & DTF_FUNC_THIS)
|
if (pdec->mBase->mFlags & DTF_FUNC_THIS)
|
||||||
{
|
{
|
||||||
Declaration* adec = pdec->mBase->mParams->Clone();
|
if (!(ndec->mBase->mFlags & DTF_FUNC_THIS))
|
||||||
adec->mNext = ndec->mBase->mParams;
|
|
||||||
|
|
||||||
if (ConsumeTokenIf(TK_CONST))
|
|
||||||
{
|
{
|
||||||
if (!(adec->mBase->mBase->mFlags & DTF_CONST))
|
Declaration* adec = pdec->mBase->mParams->Clone();
|
||||||
adec->mBase = adec->mBase->mBase->ToConstType()->BuildConstPointer(adec->mLocation);
|
adec->mNext = ndec->mBase->mParams;
|
||||||
|
|
||||||
|
if (ConsumeTokenIf(TK_CONST))
|
||||||
|
{
|
||||||
|
if (!(adec->mBase->mBase->mFlags & DTF_CONST))
|
||||||
|
adec->mBase = adec->mBase->mBase->ToConstType()->BuildConstPointer(adec->mLocation);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (adec->mBase->mBase->mFlags & DTF_CONST)
|
||||||
|
adec->mBase = adec->mBase->mBase->ToMutableType()->BuildConstPointer(adec->mLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
Declaration* p = adec->mBase->mParams;
|
||||||
|
while (p)
|
||||||
|
{
|
||||||
|
p->mVarIndex += 2;
|
||||||
|
p = p->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
ndec->mBase->mParams = adec;
|
||||||
|
|
||||||
|
ndec->mBase->mFlags |= DTF_FUNC_THIS;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (ndec->mBase->mFlags & DTF_FUNC_THIS)
|
||||||
|
{
|
||||||
|
if (pdec->mBase->mParams)
|
||||||
|
ndec->mBase->mParams = pdec->mBase->mParams->Clone();
|
||||||
else
|
else
|
||||||
{
|
ndec->mBase->mParams = nullptr;
|
||||||
if (adec->mBase->mBase->mFlags & DTF_CONST)
|
ndec->mBase->mFlags &= ~DTF_FUNC_THIS;
|
||||||
adec->mBase = adec->mBase->mBase->ToMutableType()->BuildConstPointer(adec->mLocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
Declaration* p = adec->mBase->mParams;
|
|
||||||
while (p)
|
|
||||||
{
|
|
||||||
p->mVarIndex += 2;
|
|
||||||
p = p->mNext;
|
|
||||||
}
|
|
||||||
|
|
||||||
ndec->mBase->mParams = adec;
|
|
||||||
|
|
||||||
ndec->mBase->mFlags |= DTF_FUNC_THIS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCompilerOptions & COPT_CPLUSPLUS)
|
if (mCompilerOptions & COPT_CPLUSPLUS)
|
||||||
|
@ -4777,10 +4791,14 @@ Expression* Parser::ParseLambdaExpression(void)
|
||||||
pdec->mSize = 2;
|
pdec->mSize = 2;
|
||||||
|
|
||||||
Expression* einit = nullptr;
|
Expression* einit = nullptr;
|
||||||
|
|
||||||
|
bool capture = false;
|
||||||
|
|
||||||
ConsumeToken(TK_OPEN_BRACKET);
|
ConsumeToken(TK_OPEN_BRACKET);
|
||||||
if (!ConsumeTokenIf(TK_CLOSE_BRACKET))
|
if (!ConsumeTokenIf(TK_CLOSE_BRACKET))
|
||||||
{
|
{
|
||||||
|
capture = true;
|
||||||
|
|
||||||
// Parse capture list list
|
// Parse capture list list
|
||||||
do {
|
do {
|
||||||
bool reference = false;
|
bool reference = false;
|
||||||
|
@ -4880,7 +4898,8 @@ Expression* Parser::ParseLambdaExpression(void)
|
||||||
fdec->mBase = TheConstVoidTypeDeclaration;
|
fdec->mBase = TheConstVoidTypeDeclaration;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrependThisArgument(fdec->mBase, cpdec);
|
if (capture)
|
||||||
|
PrependThisArgument(fdec->mBase, cpdec);
|
||||||
|
|
||||||
fdec->mFlags |= fdec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE);
|
fdec->mFlags |= fdec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE);
|
||||||
|
|
||||||
|
@ -5296,12 +5315,16 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mThisPointer && mThisPointer->mType == DT_ARGUMENT && !mScope->Lookup(mScanner->mTokenIdent, SLEVEL_FUNCTION))
|
if (mThisPointer && !mScope->Lookup(mScanner->mTokenIdent, SLEVEL_FUNCTION))
|
||||||
{
|
{
|
||||||
int offset;
|
int offset;
|
||||||
uint64 flags;
|
uint64 flags;
|
||||||
|
|
||||||
dec = MemberLookup(mThisPointer->mBase->mBase, mScanner->mTokenIdent, offset, flags);
|
if (mThisPointer->mType == DT_ARGUMENT)
|
||||||
|
dec = MemberLookup(mThisPointer->mBase->mBase, mScanner->mTokenIdent, offset, flags);
|
||||||
|
else if (mThisPointer->mType == DT_TYPE_POINTER)
|
||||||
|
dec = MemberLookup(mThisPointer->mBase, mScanner->mTokenIdent, offset, flags);
|
||||||
|
|
||||||
if (dec)
|
if (dec)
|
||||||
{
|
{
|
||||||
if (dec->mType == DT_ELEMENT || dec->mType == DT_CONST_FUNCTION)
|
if (dec->mType == DT_ELEMENT || dec->mType == DT_CONST_FUNCTION)
|
||||||
|
@ -5670,55 +5693,65 @@ Expression* Parser::ParseQualify(Expression* exp)
|
||||||
}
|
}
|
||||||
else if (mdec->mType == DT_CONST_FUNCTION)
|
else if (mdec->mType == DT_CONST_FUNCTION)
|
||||||
{
|
{
|
||||||
ConsumeToken(TK_OPEN_PARENTHESIS);
|
if (mdec->mBase->mFlags & DTF_FUNC_THIS)
|
||||||
|
|
||||||
nexp = new Expression(mScanner->mLocation, EX_CALL);
|
|
||||||
if (mInlineCall)
|
|
||||||
nexp->mType = EX_INLINE;
|
|
||||||
mInlineCall = false;
|
|
||||||
|
|
||||||
nexp->mLeft = new Expression(mScanner->mLocation, EX_CONSTANT);
|
|
||||||
nexp->mLeft->mDecType = mdec->mBase;
|
|
||||||
nexp->mLeft->mDecValue = mdec;
|
|
||||||
|
|
||||||
nexp->mDecType = mdec->mBase;
|
|
||||||
if (ConsumeTokenIf(TK_CLOSE_PARENTHESIS))
|
|
||||||
nexp->mRight = nullptr;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
nexp->mRight = ParseListExpression(false);
|
ConsumeToken(TK_OPEN_PARENTHESIS);
|
||||||
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
|
||||||
}
|
|
||||||
|
|
||||||
Expression* texp = new Expression(nexp->mLocation, EX_PREFIX);
|
nexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
texp->mToken = TK_BINARY_AND;
|
if (mInlineCall)
|
||||||
texp->mLeft = exp;
|
nexp->mType = EX_INLINE;
|
||||||
texp->mDecType = new Declaration(nexp->mLocation, DT_TYPE_POINTER);
|
mInlineCall = false;
|
||||||
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
|
||||||
if (exp->mDecType->mType == DT_TYPE_REFERENCE)
|
|
||||||
texp->mDecType->mBase = exp->mDecType->mBase;
|
|
||||||
else
|
|
||||||
texp->mDecType->mBase = exp->mDecType;
|
|
||||||
texp->mDecType->mSize = 2;
|
|
||||||
|
|
||||||
if (nexp->mRight)
|
nexp->mLeft = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
{
|
nexp->mLeft->mDecType = mdec->mBase;
|
||||||
Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
|
nexp->mLeft->mDecValue = mdec;
|
||||||
lexp->mLeft = texp;
|
|
||||||
lexp->mRight = nexp->mRight;
|
nexp->mDecType = mdec->mBase;
|
||||||
nexp->mRight = lexp;
|
if (ConsumeTokenIf(TK_CLOSE_PARENTHESIS))
|
||||||
|
nexp->mRight = nullptr;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nexp->mRight = ParseListExpression(false);
|
||||||
|
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression* texp = new Expression(nexp->mLocation, EX_PREFIX);
|
||||||
|
texp->mToken = TK_BINARY_AND;
|
||||||
|
texp->mLeft = exp;
|
||||||
|
texp->mDecType = new Declaration(nexp->mLocation, DT_TYPE_POINTER);
|
||||||
|
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||||
|
if (exp->mDecType->mType == DT_TYPE_REFERENCE)
|
||||||
|
texp->mDecType->mBase = exp->mDecType->mBase;
|
||||||
|
else
|
||||||
|
texp->mDecType->mBase = exp->mDecType;
|
||||||
|
texp->mDecType->mSize = 2;
|
||||||
|
|
||||||
|
if (nexp->mRight)
|
||||||
|
{
|
||||||
|
Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
|
||||||
|
lexp->mLeft = texp;
|
||||||
|
lexp->mRight = nexp->mRight;
|
||||||
|
nexp->mRight = lexp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nexp->mRight = texp;
|
||||||
|
|
||||||
|
nexp = ResolveOverloadCall(nexp);
|
||||||
|
|
||||||
|
nexp->mDecType = nexp->mLeft->mDecType->mBase;
|
||||||
|
|
||||||
|
if (nexp->mLeft->mDecType->mFlags & DTF_VIRTUAL)
|
||||||
|
nexp->mType = EX_VCALL;
|
||||||
|
|
||||||
|
exp = nexp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
nexp->mRight = texp;
|
{
|
||||||
|
nexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
nexp = ResolveOverloadCall(nexp);
|
nexp->mDecValue = mdec;
|
||||||
|
nexp->mDecType = mdec->mBase;
|
||||||
nexp->mDecType = nexp->mLeft->mDecType->mBase;
|
exp = nexp;
|
||||||
|
}
|
||||||
if (nexp->mLeft->mDecType->mFlags & DTF_VIRTUAL)
|
|
||||||
nexp->mType = EX_VCALL;
|
|
||||||
|
|
||||||
exp = nexp;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (destructor)
|
else if (destructor)
|
||||||
|
@ -6499,37 +6532,40 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parentCall = false;
|
bool parentCall = false;
|
||||||
if (thisExp)
|
if (exp->mDecType->mFlags & DTF_FUNC_THIS)
|
||||||
{
|
{
|
||||||
if (nexp->mRight)
|
if (thisExp)
|
||||||
{
|
{
|
||||||
Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
|
|
||||||
lexp->mLeft = thisExp;
|
|
||||||
lexp->mRight = nexp->mRight;
|
|
||||||
nexp->mRight = lexp;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
nexp->mRight = thisExp;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((exp->mDecType->mFlags & DTF_FUNC_THIS) && mThisPointer && mThisPointer->mType == DT_ARGUMENT)
|
|
||||||
{
|
|
||||||
Expression* texp = new Expression(mScanner->mLocation, EX_VARIABLE);
|
|
||||||
texp->mDecType = mThisPointer->mBase;
|
|
||||||
texp->mDecValue = mThisPointer;
|
|
||||||
|
|
||||||
if (nexp->mRight)
|
if (nexp->mRight)
|
||||||
{
|
{
|
||||||
Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
|
Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
|
||||||
lexp->mLeft = texp;
|
lexp->mLeft = thisExp;
|
||||||
lexp->mRight = nexp->mRight;
|
lexp->mRight = nexp->mRight;
|
||||||
nexp->mRight = lexp;
|
nexp->mRight = lexp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
nexp->mRight = texp;
|
nexp->mRight = thisExp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mThisPointer && mThisPointer->mType == DT_ARGUMENT)
|
||||||
|
{
|
||||||
|
Expression* texp = new Expression(mScanner->mLocation, EX_VARIABLE);
|
||||||
|
texp->mDecType = mThisPointer->mBase;
|
||||||
|
texp->mDecValue = mThisPointer;
|
||||||
|
|
||||||
parentCall = true;
|
if (nexp->mRight)
|
||||||
|
{
|
||||||
|
Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
|
||||||
|
lexp->mLeft = texp;
|
||||||
|
lexp->mRight = nexp->mRight;
|
||||||
|
nexp->mRight = lexp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nexp->mRight = texp;
|
||||||
|
|
||||||
|
parentCall = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8210,6 +8246,8 @@ Expression* Parser::ParseFunction(Declaration * dec)
|
||||||
|
|
||||||
if (dec->mFlags & DTF_FUNC_THIS)
|
if (dec->mFlags & DTF_FUNC_THIS)
|
||||||
mThisPointer = dec->mParams;
|
mThisPointer = dec->mParams;
|
||||||
|
else
|
||||||
|
mThisPointer = dec->mClass;
|
||||||
|
|
||||||
mFunctionType = dec;
|
mFunctionType = dec;
|
||||||
|
|
||||||
|
@ -9220,7 +9258,7 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
||||||
pdec = new Declaration(exp->mLocation, DT_TYPE_TEMPLATE);
|
pdec = new Declaration(exp->mLocation, DT_TYPE_TEMPLATE);
|
||||||
pdec->mBase = exp->mDecValue;
|
pdec->mBase = exp->mDecValue;
|
||||||
}
|
}
|
||||||
else if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_INTEGER)
|
else if (exp->mType == EX_CONSTANT && (exp->mDecValue->mType == DT_CONST_INTEGER || exp->mDecValue->mType == DT_CONST_TEMPLATE))
|
||||||
{
|
{
|
||||||
pdec = new Declaration(exp->mLocation, DT_CONST_TEMPLATE);
|
pdec = new Declaration(exp->mLocation, DT_CONST_TEMPLATE);
|
||||||
pdec->mBase = exp->mDecValue;
|
pdec->mBase = exp->mDecValue;
|
||||||
|
@ -9257,6 +9295,9 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
||||||
tdec->mBase = bdec;
|
tdec->mBase = bdec;
|
||||||
bdec->mTemplate = tdec;
|
bdec->mTemplate = tdec;
|
||||||
bdec->mBase = tmpld->mBase->mBase;
|
bdec->mBase = tmpld->mBase->mBase;
|
||||||
|
tdec->mIdent = tmpld->mIdent;
|
||||||
|
tdec->mQualIdent = tmpld->mQualIdent;
|
||||||
|
tdec->mScope->mName = tdec->mIdent;
|
||||||
tdec->mNext = tmpld;
|
tdec->mNext = tmpld;
|
||||||
bdec->mIdent = tdec->MangleIdent();
|
bdec->mIdent = tdec->MangleIdent();
|
||||||
|
|
||||||
|
@ -9511,6 +9552,7 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
||||||
|
|
||||||
tdec->mBase = ndec;
|
tdec->mBase = ndec;
|
||||||
ndec->mValue = p->ParseFunction(ndec->mBase);
|
ndec->mValue = p->ParseFunction(ndec->mBase);
|
||||||
|
ndec->mNumVars = mLocalIndex;
|
||||||
ndec->mFlags |= DTF_DEFINED;
|
ndec->mFlags |= DTF_DEFINED;
|
||||||
|
|
||||||
ndec->mIdent = ndec->mIdent->Mangle(tdec->mScope->mName->mString);
|
ndec->mIdent = ndec->mIdent->Mangle(tdec->mScope->mName->mString);
|
||||||
|
@ -9518,7 +9560,13 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tdec->mBase = p->ParseDeclaration(nullptr, true, false, tmpld->mClass, tdec);
|
Declaration* tpthis = nullptr;
|
||||||
|
if (tmpld->mClass)
|
||||||
|
tpthis = tmpld->mClass;
|
||||||
|
else if (expd && expd->mBase)
|
||||||
|
tpthis = expd->mBase->BuildConstPointer(tdec->mLocation);
|
||||||
|
|
||||||
|
tdec->mBase = p->ParseDeclaration(nullptr, true, false, tpthis, tdec);
|
||||||
}
|
}
|
||||||
|
|
||||||
p->mTemplateScope = nullptr;
|
p->mTemplateScope = nullptr;
|
||||||
|
@ -9541,15 +9589,19 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
||||||
mpdec = mpdec->mNext;
|
mpdec = mpdec->mNext;
|
||||||
if (mpdec && mpdec->mTemplate)
|
if (mpdec && mpdec->mTemplate)
|
||||||
{
|
{
|
||||||
|
Declaration* rdec;
|
||||||
if (mdec->mTemplate)
|
if (mdec->mTemplate)
|
||||||
{
|
{
|
||||||
Declaration * mtdec = p->ParseTemplateExpansion(mpdec->mTemplate, tdec);
|
Declaration * mtdec = p->ParseTemplateExpansion(mpdec->mTemplate, tdec);
|
||||||
mtdec->mClass = mdec->mTemplate->mClass;
|
mtdec->mClass = mdec->mTemplate->mClass;
|
||||||
mdec->mTemplate = mtdec;
|
mdec->mTemplate = mtdec;
|
||||||
mdec->mTemplate->mBase = mdec;
|
mdec->mTemplate->mBase = mdec;
|
||||||
|
rdec = mtdec;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
p->ParseTemplateExpansion(mpdec->mTemplate, tdec);
|
rdec = p->ParseTemplateExpansion(mpdec->mTemplate, tdec);
|
||||||
|
if (mdec->mBase->mBase->IsAuto())
|
||||||
|
mdec->mBase->mBase = rdec->mBase->mBase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9824,9 +9876,30 @@ void Parser::ParseTemplateDeclarationBody(Declaration * tdec, Declaration * pthi
|
||||||
ConsumeTokenIf(TK_CONSTEXPR);
|
ConsumeTokenIf(TK_CONSTEXPR);
|
||||||
|
|
||||||
Declaration* bdec = ParseBaseTypeDeclaration(0, true);
|
Declaration* bdec = ParseBaseTypeDeclaration(0, true);
|
||||||
Declaration* adec = ParsePostfixDeclaration();
|
Declaration* adec = nullptr;
|
||||||
|
|
||||||
adec = ReverseDeclaration(adec, bdec);
|
if (ConsumeTokenIf(TK_COLCOLON) && ExpectToken(TK_IDENT) && mScanner->mTokenIdent == bdec->mTemplate->mIdent)
|
||||||
|
{
|
||||||
|
mScanner->NextToken();
|
||||||
|
|
||||||
|
Declaration* ctdec = ParseFunctionDeclaration(TheVoidTypeDeclaration);
|
||||||
|
|
||||||
|
adec = new Declaration(ctdec->mLocation, DT_CONST_FUNCTION);
|
||||||
|
|
||||||
|
adec->mBase = ctdec;
|
||||||
|
adec->mIdent = bdec->mTemplate->mIdent->PreMangle("+");
|
||||||
|
|
||||||
|
char buffer[200];
|
||||||
|
strcpy_s(buffer, bdec->mTemplate->mQualIdent->mString);
|
||||||
|
strcat_s(buffer, "::");
|
||||||
|
strcat_s(buffer, adec->mIdent->mString);
|
||||||
|
adec->mQualIdent = Ident::Unique(buffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
adec = ParsePostfixDeclaration();
|
||||||
|
adec = ReverseDeclaration(adec, bdec);
|
||||||
|
}
|
||||||
|
|
||||||
mTemplateScope = tdec->mScope->mParent;
|
mTemplateScope = tdec->mScope->mParent;
|
||||||
|
|
||||||
|
|
|
@ -541,7 +541,7 @@ void Scanner::NextPreToken(void)
|
||||||
mPreprocessorMode = true;
|
mPreprocessorMode = true;
|
||||||
mPrepCondFalse = 0;
|
mPrepCondFalse = 0;
|
||||||
|
|
||||||
NextToken();
|
NextPreToken();
|
||||||
int64 v = PrepParseConditional();
|
int64 v = PrepParseConditional();
|
||||||
if (v)
|
if (v)
|
||||||
{
|
{
|
||||||
|
@ -612,7 +612,7 @@ void Scanner::NextPreToken(void)
|
||||||
if (mToken == TK_COMMA)
|
if (mToken == TK_COMMA)
|
||||||
{
|
{
|
||||||
mPreprocessorMode = true;
|
mPreprocessorMode = true;
|
||||||
NextToken();
|
NextPreToken();
|
||||||
int64 loopCount = PrepParseConditional();
|
int64 loopCount = PrepParseConditional();
|
||||||
mPreprocessorMode = false;
|
mPreprocessorMode = false;
|
||||||
|
|
||||||
|
@ -771,7 +771,7 @@ void Scanner::NextPreToken(void)
|
||||||
else if (mToken == TK_PREP_IF)
|
else if (mToken == TK_PREP_IF)
|
||||||
{
|
{
|
||||||
mPreprocessorMode = true;
|
mPreprocessorMode = true;
|
||||||
NextToken();
|
NextPreToken();
|
||||||
int64 v = PrepParseConditional();
|
int64 v = PrepParseConditional();
|
||||||
if (v)
|
if (v)
|
||||||
mPrepCondDepth++;
|
mPrepCondDepth++;
|
||||||
|
@ -789,7 +789,7 @@ void Scanner::NextPreToken(void)
|
||||||
{
|
{
|
||||||
const Ident* ident = mTokenIdent;
|
const Ident* ident = mTokenIdent;
|
||||||
|
|
||||||
NextToken();
|
NextPreToken();
|
||||||
|
|
||||||
int64 v = PrepParseConditional();
|
int64 v = PrepParseConditional();
|
||||||
Macro* macro = mDefines->Lookup(ident);
|
Macro* macro = mDefines->Lookup(ident);
|
||||||
|
@ -813,7 +813,7 @@ void Scanner::NextPreToken(void)
|
||||||
else if (mToken == TK_PREP_UNTIL)
|
else if (mToken == TK_PREP_UNTIL)
|
||||||
{
|
{
|
||||||
mPreprocessorMode = true;
|
mPreprocessorMode = true;
|
||||||
NextToken();
|
NextPreToken();
|
||||||
int64 v = PrepParseConditional();
|
int64 v = PrepParseConditional();
|
||||||
if (mToken != TK_EOL)
|
if (mToken != TK_EOL)
|
||||||
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "End of line expected");
|
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "End of line expected");
|
||||||
|
@ -1136,14 +1136,14 @@ void Scanner::NextRawToken(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NextChar();
|
NextChar();
|
||||||
NextToken();
|
NextPreToken();
|
||||||
}
|
}
|
||||||
else if (mTokenChar == '/')
|
else if (mTokenChar == '/')
|
||||||
{
|
{
|
||||||
NextChar();
|
NextChar();
|
||||||
while (!IsLineBreak(mTokenChar) && NextChar())
|
while (!IsLineBreak(mTokenChar) && NextChar())
|
||||||
;
|
;
|
||||||
NextToken();
|
NextPreToken();
|
||||||
}
|
}
|
||||||
else if (mTokenChar == '=')
|
else if (mTokenChar == '=')
|
||||||
{
|
{
|
||||||
|
@ -2237,32 +2237,32 @@ int64 Scanner::PrepParseSimple(void)
|
||||||
case TK_INTEGERL:
|
case TK_INTEGERL:
|
||||||
case TK_INTEGERUL:
|
case TK_INTEGERUL:
|
||||||
v = mTokenInteger;
|
v = mTokenInteger;
|
||||||
NextToken();
|
NextPreToken();
|
||||||
break;
|
break;
|
||||||
case TK_SUB:
|
case TK_SUB:
|
||||||
NextToken();
|
NextPreToken();
|
||||||
v = -PrepParseSimple();
|
v = -PrepParseSimple();
|
||||||
break;
|
break;
|
||||||
case TK_LOGICAL_NOT:
|
case TK_LOGICAL_NOT:
|
||||||
NextToken();
|
NextPreToken();
|
||||||
v = !PrepParseSimple();
|
v = !PrepParseSimple();
|
||||||
break;
|
break;
|
||||||
case TK_BINARY_NOT:
|
case TK_BINARY_NOT:
|
||||||
NextToken();
|
NextPreToken();
|
||||||
v = ~PrepParseSimple();
|
v = ~PrepParseSimple();
|
||||||
break;
|
break;
|
||||||
case TK_OPEN_PARENTHESIS:
|
case TK_OPEN_PARENTHESIS:
|
||||||
NextToken();
|
NextPreToken();
|
||||||
v = PrepParseConditional();
|
v = PrepParseConditional();
|
||||||
if (mToken == TK_CLOSE_PARENTHESIS)
|
if (mToken == TK_CLOSE_PARENTHESIS)
|
||||||
NextToken();
|
NextPreToken();
|
||||||
else
|
else
|
||||||
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "')' expected");
|
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "')' expected");
|
||||||
break;
|
break;
|
||||||
case TK_IDENT:
|
case TK_IDENT:
|
||||||
if (strcmp(mTokenIdent->mString, "defined") == 0)
|
if (strcmp(mTokenIdent->mString, "defined") == 0)
|
||||||
{
|
{
|
||||||
NextToken();
|
NextPreToken();
|
||||||
if (mToken == TK_OPEN_PARENTHESIS)
|
if (mToken == TK_OPEN_PARENTHESIS)
|
||||||
{
|
{
|
||||||
NextRawToken();
|
NextRawToken();
|
||||||
|
@ -2277,13 +2277,13 @@ int64 Scanner::PrepParseSimple(void)
|
||||||
v = 1;
|
v = 1;
|
||||||
else
|
else
|
||||||
v = 0;
|
v = 0;
|
||||||
NextToken();
|
NextPreToken();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Identifier expected");
|
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Identifier expected");
|
||||||
|
|
||||||
if (mToken == TK_CLOSE_PARENTHESIS)
|
if (mToken == TK_CLOSE_PARENTHESIS)
|
||||||
NextToken();
|
NextPreToken();
|
||||||
else
|
else
|
||||||
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "')' expected");
|
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "')' expected");
|
||||||
}
|
}
|
||||||
|
@ -2296,7 +2296,7 @@ int64 Scanner::PrepParseSimple(void)
|
||||||
default:
|
default:
|
||||||
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Invalid preprocessor token", TokenName(mToken));
|
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Invalid preprocessor token", TokenName(mToken));
|
||||||
if (mToken != TK_EOL)
|
if (mToken != TK_EOL)
|
||||||
NextToken();
|
NextPreToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
|
@ -2311,11 +2311,11 @@ int64 Scanner::PrepParseMul(void)
|
||||||
switch (mToken)
|
switch (mToken)
|
||||||
{
|
{
|
||||||
case TK_MUL:
|
case TK_MUL:
|
||||||
NextToken();
|
NextPreToken();
|
||||||
v *= PrepParseSimple();
|
v *= PrepParseSimple();
|
||||||
break;
|
break;
|
||||||
case TK_DIV:
|
case TK_DIV:
|
||||||
NextToken();
|
NextPreToken();
|
||||||
u = PrepParseSimple();
|
u = PrepParseSimple();
|
||||||
if (u == 0)
|
if (u == 0)
|
||||||
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Division by zero");
|
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Division by zero");
|
||||||
|
@ -2343,11 +2343,11 @@ int64 Scanner::PrepParseAdd(void)
|
||||||
switch (mToken)
|
switch (mToken)
|
||||||
{
|
{
|
||||||
case TK_ADD:
|
case TK_ADD:
|
||||||
NextToken();
|
NextPreToken();
|
||||||
v += PrepParseMul();
|
v += PrepParseMul();
|
||||||
break;
|
break;
|
||||||
case TK_SUB:
|
case TK_SUB:
|
||||||
NextToken();
|
NextPreToken();
|
||||||
v -= PrepParseMul();
|
v -= PrepParseMul();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -2364,11 +2364,11 @@ int64 Scanner::PrepParseShift(void)
|
||||||
switch (mToken)
|
switch (mToken)
|
||||||
{
|
{
|
||||||
case TK_LEFT_SHIFT:
|
case TK_LEFT_SHIFT:
|
||||||
NextToken();
|
NextPreToken();
|
||||||
v <<= PrepParseAdd();
|
v <<= PrepParseAdd();
|
||||||
break;
|
break;
|
||||||
case TK_RIGHT_SHIFT:
|
case TK_RIGHT_SHIFT:
|
||||||
NextToken();
|
NextPreToken();
|
||||||
v >>= PrepParseAdd();
|
v >>= PrepParseAdd();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -2385,27 +2385,27 @@ int64 Scanner::PrepParseRel(void)
|
||||||
switch (mToken)
|
switch (mToken)
|
||||||
{
|
{
|
||||||
case TK_LESS_THAN:
|
case TK_LESS_THAN:
|
||||||
NextToken();
|
NextPreToken();
|
||||||
v = v < PrepParseShift();
|
v = v < PrepParseShift();
|
||||||
break;
|
break;
|
||||||
case TK_GREATER_THAN:
|
case TK_GREATER_THAN:
|
||||||
NextToken();
|
NextPreToken();
|
||||||
v = v > PrepParseShift();
|
v = v > PrepParseShift();
|
||||||
break;
|
break;
|
||||||
case TK_LESS_EQUAL:
|
case TK_LESS_EQUAL:
|
||||||
NextToken();
|
NextPreToken();
|
||||||
v = v <= PrepParseShift();
|
v = v <= PrepParseShift();
|
||||||
break;
|
break;
|
||||||
case TK_GREATER_EQUAL:
|
case TK_GREATER_EQUAL:
|
||||||
NextToken();
|
NextPreToken();
|
||||||
v = v >= PrepParseShift();
|
v = v >= PrepParseShift();
|
||||||
break;
|
break;
|
||||||
case TK_EQUAL:
|
case TK_EQUAL:
|
||||||
NextToken();
|
NextPreToken();
|
||||||
v = v == PrepParseShift();
|
v = v == PrepParseShift();
|
||||||
break;
|
break;
|
||||||
case TK_NOT_EQUAL:
|
case TK_NOT_EQUAL:
|
||||||
NextToken();
|
NextPreToken();
|
||||||
v = v != PrepParseShift();
|
v = v != PrepParseShift();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -2420,7 +2420,7 @@ int64 Scanner::PrepParseBinaryAnd(void)
|
||||||
int64 v = PrepParseRel();
|
int64 v = PrepParseRel();
|
||||||
while (mToken == TK_BINARY_AND)
|
while (mToken == TK_BINARY_AND)
|
||||||
{
|
{
|
||||||
NextToken();
|
NextPreToken();
|
||||||
v &= PrepParseRel();
|
v &= PrepParseRel();
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
|
@ -2431,7 +2431,7 @@ int64 Scanner::PrepParseBinaryXor(void)
|
||||||
int64 v = PrepParseBinaryAnd();
|
int64 v = PrepParseBinaryAnd();
|
||||||
while (mToken == TK_BINARY_XOR)
|
while (mToken == TK_BINARY_XOR)
|
||||||
{
|
{
|
||||||
NextToken();
|
NextPreToken();
|
||||||
v ^= PrepParseBinaryAnd();
|
v ^= PrepParseBinaryAnd();
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
|
@ -2442,7 +2442,7 @@ int64 Scanner::PrepParseBinaryOr(void)
|
||||||
int64 v = PrepParseBinaryXor();
|
int64 v = PrepParseBinaryXor();
|
||||||
while (mToken == TK_BINARY_OR)
|
while (mToken == TK_BINARY_OR)
|
||||||
{
|
{
|
||||||
NextToken();
|
NextPreToken();
|
||||||
v |= PrepParseBinaryXor();
|
v |= PrepParseBinaryXor();
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
|
@ -2453,7 +2453,7 @@ int64 Scanner::PrepParseLogicalAnd(void)
|
||||||
int64 v = PrepParseBinaryOr();
|
int64 v = PrepParseBinaryOr();
|
||||||
while (mToken == TK_LOGICAL_AND)
|
while (mToken == TK_LOGICAL_AND)
|
||||||
{
|
{
|
||||||
NextToken();
|
NextPreToken();
|
||||||
if (!PrepParseBinaryOr())
|
if (!PrepParseBinaryOr())
|
||||||
v = 0;
|
v = 0;
|
||||||
}
|
}
|
||||||
|
@ -2465,7 +2465,7 @@ int64 Scanner::PrepParseLogicalOr(void)
|
||||||
int64 v = PrepParseLogicalAnd();
|
int64 v = PrepParseLogicalAnd();
|
||||||
while (mToken == TK_LOGICAL_OR)
|
while (mToken == TK_LOGICAL_OR)
|
||||||
{
|
{
|
||||||
NextToken();
|
NextPreToken();
|
||||||
if (PrepParseLogicalAnd())
|
if (PrepParseLogicalAnd())
|
||||||
v = 1;
|
v = 1;
|
||||||
}
|
}
|
||||||
|
@ -2477,10 +2477,10 @@ int64 Scanner::PrepParseConditional(void)
|
||||||
int64 v = PrepParseLogicalOr();
|
int64 v = PrepParseLogicalOr();
|
||||||
if (mToken == TK_QUESTIONMARK)
|
if (mToken == TK_QUESTIONMARK)
|
||||||
{
|
{
|
||||||
NextToken();
|
NextPreToken();
|
||||||
int64 vt = PrepParseConditional();
|
int64 vt = PrepParseConditional();
|
||||||
if (mToken == TK_COLON)
|
if (mToken == TK_COLON)
|
||||||
NextToken();
|
NextPreToken();
|
||||||
else
|
else
|
||||||
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "':' expected");
|
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "':' expected");
|
||||||
int64 vf = PrepParseConditional();
|
int64 vf = PrepParseConditional();
|
||||||
|
|
Loading…
Reference in New Issue