Mangling function types in template expansion

This commit is contained in:
drmortalwombat 2023-08-18 23:03:15 +02:00
parent 3a9cd85072
commit 8dc37e9ab2
11 changed files with 582 additions and 59 deletions

View File

@ -35,6 +35,32 @@ void sort(T s, T e)
} }
} }
template<class T, class LF>
void sort(T s, T e, LF lt)
{
while (s != e)
{
auto p = s;
auto q = s;
q++;
while (q != e)
{
if (lt(*q, *p))
{
swap(*q, *p);
p++;
swap(*q, *p);
}
q++;
}
sort(s, p, lt);
p++;
s = p;
}
}
template<class II, class OI> template<class II, class OI>
OI copy(II first, II last, OI result) OI copy(II first, II last, OI result)
{ {

207
include/opp/bidxlist.h Normal file
View File

@ -0,0 +1,207 @@
#ifndef OPP_BIDXLIST_H
#ifndef OPP_BIDXLIST_H
template <class T, int n>
class bindexlist
{
public:
char _free;
char _pred[n], _succ[n];
T _data[n];
class iterator
{
public:
bindexlist * _l;
char _i;
iterator(void) : _l(nullptr) {}
iterator(bindexlist * l, char i)
: _l(l), _i(i) {}
iterator(const iterator & li) : _l(li._l), _i(li._i) {}
iterator & operator=(const iterator & li)
{
_l = li._l;
_i = li._i;
return *this;
}
T & operator*()
{
return _l->_data[_i];
}
T * operator->()
{
return _l->_data + _i;
}
iterator & operator++(void)
{
_i = _l->_succ[_i];
return *this;
}
iterator operator++(int)
{
char i = _i;
_i = _l->_succ[_i];
return bindexlist::iterator(_l, i);
}
iterator & operator+=(char n)
{
while (n--)
_i = _l->_succ[_i];
return *this;
}
iterator & operator--(void)
{
_i = _l->_pred[_i];
return *this;
}
iterator operator++(int)
{
char i = _i;
_i = _l->_pred[_i];
return bindexlist::iterator(_l, i);
}
iterator & operator-=(char n)
{
while (n--)
_i = _l->_pred[_i];
return *this;
}
bool operator==(const iterator & li)
{
return _i == li._i;
}
bool operator!=(const iterator & li)
{
return _i != li._i;
}
};
public:
typedef T element_type;
typedef iterator iterator_type;
bindexlist(void)
{
_succ[0] = 0;
_pred[0] = 0;
for(char i=1; i<n; i++)
_succ[i] = i + 1;
_free = 1;
}
~bindexlist(void)
{
}
iterator begin(void)
{
return iterator(this, _succ[0]);
}
iterator end(void)
{
return iterator(this, 0);
}
T & front(void)
{
return _data[_succ[0]];
}
const T & front(void) const
{
return _data[_succ[0]];
}
T & back(void)
{
return _data[_pred[0]];
}
const T & back(void) const
{
return _data[_pred[0]];
}
iterator erase(iterator it)
{
char s = _succ[it._i];
_succ[_pred[it._i]] = _pred[it._i];
_pred[_succ[it._i]] = s;
_succ[it._i] = _free;
_free = it._i;
return iterator(this, s);
}
iterator erase(iterator first, iterator last)
{
char s = _succ[last._i];
_succ[_pred[last._i]] = _pred[first._i];
_pred[_succ[first._i]] = s;
_succ[last._i] = _free;
_free = first._i;
return iterator(this, s);
}
void pop_front(void)
{
char i = _succ[0];
char s = _succ[i];
_pred[s] = 0;
_succ[0] = s;
_succ[i] = _free;
_free = i;
}
void pop_back(void)
{
char i = _pred[0];
char p = _pred[i];
_succ[p] = 0;
_pred[0] = p;
_pred[i] = _free;
_free = i;
}
void push_back(const T & t)
{
char i = _free;
_data[i] = t;
_free = _succ[_free];
_succ[i] = 0;
_pred[i] = _pred[0];
_succ[_pred[0]] = i;
_pred[0] = i;
}
void push_front(const T & t)
{
char i = _free;
_data[i] = t;
_free = _succ[_free];
_succ[i] = 0;
_succ[i] = _succ[0];
_pred[_succ[0]] = i;
_succ[0] = i;
}
};
#endif

View File

@ -5,17 +5,23 @@ namespace opp
{ {
template <class T> template <class T>
class listnode class listhead
{ {
public: public:
listnode * succ, * pred; listnode<T> * succ, * pred;
T data;
listnode() listhead()
{ {
succ = this; succ = (listnode<T> *)this;
pred = this; pred = (listnode<T> *)this;
} }
};
template <class T>
class listnode : public listhead<T>
{
public:
T data;
listnode(const T & t) : data(t) {} listnode(const T & t) : data(t) {}
listnode(T && t) : data(t) {} listnode(T && t) : data(t) {}
@ -41,6 +47,11 @@ public:
return node->data; return node->data;
} }
T * operator->()
{
return &(node->data);
}
list_iterator & operator++(void) list_iterator & operator++(void)
{ {
node = node->succ; node = node->succ;
@ -98,7 +109,8 @@ template <class T>
class list class list
{ {
private: private:
listnode<T> node; typedef listnode<T> ln;
listhead<T> head;
public: public:
typedef T element_type; typedef T element_type;
typedef list_iterator<T> iterator_type; typedef list_iterator<T> iterator_type;
@ -108,8 +120,8 @@ public:
~list(void) ~list(void)
{ {
listnode<T> * n = node.succ; listnode<T> * n = head.succ;
while (n != &node) while (n != &head)
{ {
listnode<T> * m = n->succ; listnode<T> * m = n->succ;
delete n; delete n;
@ -119,32 +131,32 @@ public:
list_iterator<T> begin(void) list_iterator<T> begin(void)
{ {
return list_iterator<T>(node.succ); return list_iterator<T>(head.succ);
} }
list_iterator<T> end(void) list_iterator<T> end(void)
{ {
return list_iterator<T>(&node); return list_iterator<T>((listnode<T> *)&head);
} }
T & front(void) T & front(void)
{ {
return node.succ->data; return head.succ->data;
} }
const T & front(void) const const T & front(void) const
{ {
return node.succ->data; return head.succ->data;
} }
T & back(void) T & back(void)
{ {
return node.pred->data; return head.pred->data;
} }
const T & back(void) const const T & back(void) const
{ {
return node.pred->data; return head.pred->data;
} }
list_iterator<T> erase(list_iterator<T> it); list_iterator<T> erase(list_iterator<T> it);
@ -171,18 +183,18 @@ public:
template <class T> template <class T>
void list<T>::pop_front(void) void list<T>::pop_front(void)
{ {
listnode<T> * n = node.succ; listnode<T> * n = head.succ;
node.succ = n->succ; head.succ = n->succ;
n->succ->pred = &node; n->succ->pred = (listnode<T> *)&head;
delete n; delete n;
} }
template <class T> template <class T>
void list<T>::pop_back(void) void list<T>::pop_back(void)
{ {
listnode<T> * n = node.pred; listnode<T> * n = head.pred;
node.pred = n->pred; head.pred = n->pred;
n->pred->succ = &node; n->pred->succ = (listnode<T> *)&head;
delete n; delete n;
} }
@ -190,40 +202,40 @@ template <class T>
void list<T>::push_front(const T & t) void list<T>::push_front(const T & t)
{ {
listnode<T> * n = new listnode<T>(t); listnode<T> * n = new listnode<T>(t);
n->pred = &node; n->pred = (listnode<T> *)&head;
n->succ = node.succ; n->succ = head.succ;
node.succ->pred = n; head.succ->pred = n;
node.succ = n; head.succ = n;
} }
template <class T> template <class T>
void list<T>::push_front(T && t) void list<T>::push_front(T && t)
{ {
listnode<T> * n = new listnode<T>(t); listnode<T> * n = new listnode<T>(t);
n->pred = &node; n->pred = (listnode<T> *)&head;
n->succ = node.succ; n->succ = head.succ;
node.succ->pred = n; head.succ->pred = n;
node.succ = n; head.succ = n;
} }
template <class T> template <class T>
void list<T>::push_back(const T & t) void list<T>::push_back(const T & t)
{ {
listnode<T> * n = new listnode<T>(t); listnode<T> * n = new listnode<T>(t);
n->succ = &node; n->succ = (listnode<T> *)&head;
n->pred = node.pred; n->pred = head.pred;
node.pred->succ = n; head.pred->succ = n;
node.pred = n; head.pred = n;
} }
template <class T> template <class T>
void list<T>::push_back(T && t) void list<T>::push_back(T && t)
{ {
listnode<T> * n = new listnode<T>(t); listnode<T> * n = new listnode<T>(t);
n->succ = &node; n->succ = (listnode<T> *)&head;
n->pred = node.pred; n->pred = head.pred;
node.pred->succ = n; head.pred->succ = n;
node.pred = n; head.pred = n;
} }

View File

@ -954,6 +954,20 @@ const Ident* Declaration::MangleIdent(void)
{ {
mMangleIdent = mQualIdent; mMangleIdent = mQualIdent;
} }
else if (mType == DT_TYPE_FUNCTION)
{
mMangleIdent = mBase->MangleIdent();
mMangleIdent = mMangleIdent->Mangle("(*)(");
Declaration* dec = mParams;
while (dec)
{
mMangleIdent = mMangleIdent->Mangle(dec->mBase->MangleIdent()->mString);
dec = dec->mNext;
if (dec)
mMangleIdent = mMangleIdent->Mangle(",");
}
mMangleIdent = mMangleIdent->Mangle(")");
}
else if (mType == DT_TYPE_INTEGER) else if (mType == DT_TYPE_INTEGER)
{ {
char buffer[20]; char buffer[20];
@ -964,6 +978,10 @@ const Ident* Declaration::MangleIdent(void)
{ {
mMangleIdent = Ident::Unique("float"); mMangleIdent = Ident::Unique("float");
} }
else if (mType == DT_TYPE_BOOL)
{
mMangleIdent = Ident::Unique("bool");
}
else if (mType == DT_TYPE_REFERENCE) else if (mType == DT_TYPE_REFERENCE)
{ {
mMangleIdent = mBase->MangleIdent()->PreMangle("&"); mMangleIdent = mBase->MangleIdent()->PreMangle("&");
@ -1172,6 +1190,36 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
return true; return true;
} }
else if (tdec->mType == DT_TYPE_STRUCT && fdec->mType == DT_TYPE_STRUCT && tdec->mTemplate)
{
Declaration *ftdec = tdec->mTemplate;
while (ftdec)
{
if (ftdec->mBase == fdec)
{
Declaration* fpdec = ftdec->mParams;
Declaration* tpdec = tdec->mTemplate->mParams;
while (fpdec)
{
if (tpdec->mBase->mType == DT_TYPE_TEMPLATE || tpdec->mBase->mType == DT_CONST_TEMPLATE)
{
Declaration * pdec = mScope->Insert(tpdec->mIdent, fpdec->mBase);
if (pdec && !pdec->IsSame(fpdec->mBase))
return false;
}
fpdec = fpdec->mNext;
tpdec = tpdec->mNext;
}
return true;
}
ftdec = ftdec->mNext;
}
return false;
}
else else
return tdec->CanAssign(fdec); return tdec->CanAssign(fdec);
} }
@ -1632,7 +1680,9 @@ bool Declaration::IsSame(const Declaration* dec) const
if ((mFlags & (DTF_SIGNED | DTF_CONST | DTF_VOLATILE)) != (dec->mFlags & (DTF_SIGNED | DTF_CONST | DTF_VOLATILE))) if ((mFlags & (DTF_SIGNED | DTF_CONST | DTF_VOLATILE)) != (dec->mFlags & (DTF_SIGNED | DTF_CONST | DTF_VOLATILE)))
return false; return false;
if (mType == DT_TYPE_INTEGER) if (mType == DT_CONST_INTEGER)
return mInteger == dec->mInteger;
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)
return true; return true;

View File

@ -4548,6 +4548,10 @@ 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->mCode == IC_STORE)
{
assert(code->mSrc[1].mOperandSize > 0);
}
if (code->mDst.mTemp >= 0) if (code->mDst.mTemp >= 0)
assert(code->mDst.mType != IT_NONE); assert(code->mDst.mType != IT_NONE);
for (int i = 0; i < code->mNumOperands; i++) for (int i = 0; i < code->mNumOperands; i++)
@ -7484,7 +7488,28 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
if (s0 < 0) if (s0 < 0)
{ {
mTrueValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst); mTrueValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst);
mTrueValueRange[s1].LimitMinWeak(SignedTypeMin(mInstructions[sz - 2]->mSrc[1].mType));
mFalseValueRange[s1].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst + 1); mFalseValueRange[s1].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst + 1);
mFalseValueRange[s1].LimitMaxWeak(SignedTypeMax(mInstructions[sz - 2]->mSrc[1].mType));
}
else if (s1 < 0)
{
mTrueValueRange[s0].LimitMin(mInstructions[sz - 2]->mSrc[1].mIntConst);
mTrueValueRange[s0].LimitMaxWeak(SignedTypeMax(mInstructions[sz - 2]->mSrc[0].mType));
mFalseValueRange[s0].LimitMax(mInstructions[sz - 2]->mSrc[1].mIntConst - 1);
mFalseValueRange[s0].LimitMinWeak(SignedTypeMin(mInstructions[sz - 2]->mSrc[0].mType));
}
else
{
if (mLocalValueRange[s0].mMaxState == IntegerValueRange::S_BOUND)
mFalseValueRange[s1].LimitMin(mLocalValueRange[s0].mMinValue + 1);
if (mLocalValueRange[s0].mMinState == IntegerValueRange::S_BOUND)
mTrueValueRange[s1].LimitMax(mLocalValueRange[s0].mMaxValue);
if (mLocalValueRange[s1].mMaxState == IntegerValueRange::S_BOUND)
mFalseValueRange[s0].LimitMax(mLocalValueRange[s1].mMaxValue - 1);
if (mLocalValueRange[s1].mMinState == IntegerValueRange::S_BOUND)
mTrueValueRange[s0].LimitMin(mLocalValueRange[s1].mMinValue);
} }
break; break;
case IA_CMPGS: case IA_CMPGS:
@ -8247,6 +8272,44 @@ bool InterCodeBasicBlock::RemoveUnusedResultInstructions(void)
return changed; return changed;
} }
bool InterCodeBasicBlock::RemoveUnusedLocalStoreInstructions(void)
{
bool changed = false;
if (!mVisited)
{
mVisited = true;
if (mInstructions.Size() > 0 && mInstructions.Last()->mCode == IC_RETURN)
{
int i = mInstructions.Size();
while (i > 0)
{
i--;
InterInstruction* ins = mInstructions[i];
if (ins->mCode == IC_STORE && ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mMemory == IM_LOCAL)
{
ins->mCode = IC_NONE;
ins->mNumOperands = 0;
changed = true;
}
else if (ins->mCode == IC_LOAD)
break;
else if (ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE)
break;
else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY)
break;
}
}
if (mTrueJump && mTrueJump->RemoveUnusedLocalStoreInstructions())
changed = true;
if (mFalseJump && mFalseJump->RemoveUnusedLocalStoreInstructions())
changed = true;
}
return false;
}
void InterCodeBasicBlock::BuildCallerSaveTempSet(NumberSet& callerSaveTemps) void InterCodeBasicBlock::BuildCallerSaveTempSet(NumberSet& callerSaveTemps)
{ {
if (!mVisited) if (!mVisited)
@ -16371,6 +16434,15 @@ void InterCodeProcedure::RemoveUnusedInstructions(void)
} while (mEntryBlock->RemoveUnusedResultInstructions()); } while (mEntryBlock->RemoveUnusedResultInstructions());
} }
void InterCodeProcedure::RemoveUnusedLocalStoreInstructions(void)
{
if (mCompilerOptions & COPT_OPTIMIZE_BASIC)
{
ResetVisited();
mEntryBlock->RemoveUnusedLocalStoreInstructions();
}
}
void InterCodeProcedure::RemoveUnusedStoreInstructions(InterMemory paramMemory) void InterCodeProcedure::RemoveUnusedStoreInstructions(InterMemory paramMemory)
{ {
if (mCompilerOptions & COPT_OPTIMIZE_BASIC) if (mCompilerOptions & COPT_OPTIMIZE_BASIC)
@ -16849,7 +16921,7 @@ void InterCodeProcedure::Close(void)
{ {
GrowingTypeArray tstack(IT_NONE); GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "main"); CheckFunc = !strcmp(mIdent->mString, "opp::sort<struct bindexlist<i16,10>::iterator,>");
mEntryBlock = mBlocks[0]; mEntryBlock = mBlocks[0];
@ -17471,6 +17543,8 @@ void InterCodeProcedure::Close(void)
RemoveUnusedInstructions(); RemoveUnusedInstructions();
#endif #endif
RemoveUnusedLocalStoreInstructions();
#if 1 #if 1
ResetVisited(); ResetVisited();
@ -18370,7 +18444,7 @@ void InterCodeProcedure::Disassemble(FILE* file)
void InterCodeProcedure::Disassemble(const char* name, bool dumpSets) void InterCodeProcedure::Disassemble(const char* name, bool dumpSets)
{ {
#if 0 #if 1
#ifdef _WIN32 #ifdef _WIN32
FILE* file; FILE* file;
static bool initial = true; static bool initial = true;

View File

@ -422,6 +422,7 @@ public:
void BuildCallerSaveTempSet(NumberSet& callerSaveTemps); void BuildCallerSaveTempSet(NumberSet& callerSaveTemps);
void BuildConstTempSets(void); void BuildConstTempSets(void);
bool PropagateConstOperationsUp(void); bool PropagateConstOperationsUp(void);
bool RemoveUnusedLocalStoreInstructions(void);
void BuildLocalVariableSets(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory); void BuildLocalVariableSets(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory);
void BuildGlobalProvidedVariableSet(const GrowingVariableArray& localVars, NumberSet fromProvidedVars, const GrowingVariableArray& params, NumberSet fromProvidedParams, InterMemory paramMemory); void BuildGlobalProvidedVariableSet(const GrowingVariableArray& localVars, NumberSet fromProvidedVars, const GrowingVariableArray& params, NumberSet fromProvidedParams, InterMemory paramMemory);
@ -659,6 +660,7 @@ protected:
void BuildLoopPrefix(void); void BuildLoopPrefix(void);
void SingleAssignmentForwarding(void); void SingleAssignmentForwarding(void);
void RemoveUnusedStoreInstructions(InterMemory paramMemory); void RemoveUnusedStoreInstructions(InterMemory paramMemory);
void RemoveUnusedLocalStoreInstructions(void);
void MergeCommonPathInstructions(void); void MergeCommonPathInstructions(void);
void PushSinglePathResultInstructions(void); void PushSinglePathResultInstructions(void);
void CollectVariables(InterMemory paramMemory); void CollectVariables(InterMemory paramMemory);

View File

@ -3276,7 +3276,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
} }
else else
{ {
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_POINTER && vr.mType->mType == DT_TYPE_INTEGER && texp->mType == EX_CONSTANT && texp->mDecValue->mType == DT_CONST_INTEGER && texp->mDecValue->mInteger == 0) else if (pdec && pdec->mBase->mType == DT_TYPE_POINTER && vr.mType->mType == DT_TYPE_INTEGER && texp->mType == EX_CONSTANT && texp->mDecValue->mType == DT_CONST_INTEGER && texp->mDecValue->mInteger == 0)
{ {
@ -3316,7 +3316,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 || pdec->mBase->mType == DT_TYPE_RVALUEREF) if (pdec->mBase->mType == DT_TYPE_ARRAY || pdec->mBase->mType == DT_TYPE_REFERENCE || pdec->mBase->mType == DT_TYPE_RVALUEREF || pdec->mBase->mType == DT_TYPE_FUNCTION)
{ {
wins->mSrc[1].mOperandSize = 2; wins->mSrc[1].mOperandSize = 2;
wins->mSrc[0].mType = IT_POINTER; wins->mSrc[0].mType = IT_POINTER;

View File

@ -13623,6 +13623,7 @@ bool NativeCodeBasicBlock::ForwardAXYReg(void)
bool xisa = false, yisa = false; bool xisa = false, yisa = false;
int xoffset = -1, yoffset = -1; int xoffset = -1, yoffset = -1;
int zpx = -1, zpy = -1, zpa = -1;
for (int i = 0; i < mIns.Size(); i++) for (int i = 0; i < mIns.Size(); i++)
{ {
@ -13630,33 +13631,103 @@ bool NativeCodeBasicBlock::ForwardAXYReg(void)
{ {
xisa = true; xisa = true;
xoffset = i; xoffset = i;
zpx = zpa;
} }
else if (mIns[i].mType == ASMIT_TXA) else if (mIns[i].mType == ASMIT_TXA)
{ {
xisa = true; xisa = true;
yisa = false; yisa = false;
xoffset = i; xoffset = i;
zpa = zpx;
} }
else if (mIns[i].mType == ASMIT_TAY) else if (mIns[i].mType == ASMIT_TAY)
{ {
yisa = true; yisa = true;
yoffset = i; yoffset = i;
zpy = zpa;
} }
else if (mIns[i].mType == ASMIT_TYA) else if (mIns[i].mType == ASMIT_TYA)
{ {
yisa = true; yisa = true;
xisa = false; xisa = false;
yoffset = i; yoffset = i;
zpa = zpy;
} }
else if (mIns[i].ChangesXReg()) else if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE)
{
if (zpx == mIns[i].mAddress)
{
mIns[i].mType = ASMIT_TXA; mIns[i].mMode = ASMIM_IMPLIED;
xisa = true;
yisa = false;
int j = i;
while (j > 0 && !(mIns[j - 1].mLive & LIVE_CPU_REG_X))
{
mIns[j - 1].mLive |= LIVE_CPU_REG_X;
j--;
}
}
else if (zpy == mIns[i].mAddress)
{
mIns[i].mType = ASMIT_TYA; mIns[i].mMode = ASMIM_IMPLIED;
yisa = true;
xisa = false; xisa = false;
else if (mIns[i].ChangesYReg()) int j = i;
xisa = false; while (j > 0 && !(mIns[j - 1].mLive & LIVE_CPU_REG_Y))
else if (mIns[i].ChangesAccu()) {
mIns[j - 1].mLive |= LIVE_CPU_REG_Y;
j--;
}
}
else
{ {
xisa = false; xisa = false;
yisa = false; yisa = false;
} }
zpa = mIns[i].mAddress;
}
else if (mIns[i].mType == ASMIT_LDX && mIns[i].mMode == ASMIM_ZERO_PAGE)
{
xisa = false;
zpx = mIns[i].mAddress;
}
else if (mIns[i].mType == ASMIT_LDY && mIns[i].mMode == ASMIM_ZERO_PAGE)
{
yisa = false;
zpy = mIns[i].mAddress;
}
else if (mIns[i].mType == ASMIT_STA && mIns[i].mMode == ASMIM_ZERO_PAGE)
{
zpa = mIns[i].mAddress;
if (yisa)
zpy = mIns[i].mAddress;
else if (zpy == mIns[i].mAddress)
zpy = -1;
if (xisa)
zpx = mIns[i].mAddress;
else if (zpx == mIns[i].mAddress)
zpx = -1;
}
else if (mIns[i].mType == ASMIT_STX && mIns[i].mMode == ASMIM_ZERO_PAGE)
{
zpx = mIns[i].mAddress;
if (xisa)
zpa = mIns[i].mAddress;
else if (zpa == mIns[i].mAddress)
zpa = -1;
if (zpy == mIns[i].mAddress)
zpy = -1;
}
else if (mIns[i].mType == ASMIT_STY && mIns[i].mMode == ASMIM_ZERO_PAGE)
{
zpy = mIns[i].mAddress;
if (yisa)
zpa = mIns[i].mAddress;
else if (zpa == mIns[i].mAddress)
zpa = -1;
if (zpx == mIns[i].mAddress)
zpx = -1;
}
else if (i + 1 < mIns.Size() && mIns[i].mType == ASMIT_CLC && else if (i + 1 < mIns.Size() && mIns[i].mType == ASMIT_CLC &&
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE && !(mIns[i + 1].mLive & LIVE_CPU_REG_C)) mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE && !(mIns[i + 1].mLive & LIVE_CPU_REG_C))
{ {
@ -13685,6 +13756,33 @@ bool NativeCodeBasicBlock::ForwardAXYReg(void)
} }
} }
} }
else
{
if (mIns[i].ChangesXReg())
{
xisa = false;
zpx = -1;
}
if (mIns[i].ChangesYReg())
{
yisa = false;
zpy = -1;
}
if (mIns[i].ChangesAccu())
{
xisa = false;
yisa = false;
zpa = -1;
}
if (zpa >= 0 && mIns[i].ChangesZeroPage(zpa))
zpa = -1;
if (zpx >= 0 && mIns[i].ChangesZeroPage(zpx))
zpx = -1;
if (zpy >= 0 && mIns[i].ChangesZeroPage(zpy))
zpy = -1;
}
} }
if (mTrueJump && mTrueJump->ForwardAXYReg()) if (mTrueJump && mTrueJump->ForwardAXYReg())
@ -40817,7 +40915,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{ {
mInterProc = proc; mInterProc = proc;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "test_pab50"); CheckFunc = !strcmp(mInterProc->mIdent->mString, "main");
int nblocks = proc->mBlocks.Size(); int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks]; tblocks = new NativeCodeBasicBlock * [nblocks];

View File

@ -119,7 +119,7 @@ void Parser::AddMemberFunction(Declaration* dec, Declaration* mdec)
dec->mScope->Insert(mdec->mIdent, mdec); dec->mScope->Insert(mdec->mIdent, mdec);
} }
Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt) Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaration* ptempl)
{ {
const Ident* structName = nullptr; const Ident* structName = nullptr;
@ -169,6 +169,9 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
dec->mScope = new DeclarationScope(nullptr, SLEVEL_CLASS, dec->mQualIdent); dec->mScope = new DeclarationScope(nullptr, SLEVEL_CLASS, dec->mQualIdent);
} }
if (ptempl)
ptempl->mBase = dec;
if ((mCompilerOptions & COPT_CPLUSPLUS) && mScanner->mToken == TK_COLON) if ((mCompilerOptions & COPT_CPLUSPLUS) && mScanner->mToken == TK_COLON)
{ {
mScanner->NextToken(); mScanner->NextToken();
@ -181,7 +184,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
else if (ConsumeTokenIf(TK_PRIVATE)) else if (ConsumeTokenIf(TK_PRIVATE))
pflags |= DTF_PRIVATE | DTF_PROTECTED; pflags |= DTF_PRIVATE | DTF_PROTECTED;
Declaration* pdec = ParseQualIdent(); Declaration* pdec = ParseBaseTypeDeclaration(0, false);
if (pdec) if (pdec)
{ {
if (pdec->mType == DT_TYPE_STRUCT) if (pdec->mType == DT_TYPE_STRUCT)
@ -481,7 +484,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
return dec; return dec;
} }
Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified) Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified, Declaration* ptempl)
{ {
Declaration* dec = nullptr; Declaration* dec = nullptr;
const Ident* pident = nullptr; const Ident* pident = nullptr;
@ -758,13 +761,13 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified)
break; break;
} }
case TK_STRUCT: case TK_STRUCT:
dec = ParseStructDeclaration(flags, DT_TYPE_STRUCT); dec = ParseStructDeclaration(flags, DT_TYPE_STRUCT, ptempl);
break; break;
case TK_CLASS: case TK_CLASS:
dec = ParseStructDeclaration(flags | DTF_PRIVATE | DTF_PROTECTED, DT_TYPE_STRUCT); dec = ParseStructDeclaration(flags | DTF_PRIVATE | DTF_PROTECTED, DT_TYPE_STRUCT, ptempl);
break; break;
case TK_UNION: case TK_UNION:
dec = ParseStructDeclaration(flags, DT_TYPE_UNION); dec = ParseStructDeclaration(flags, DT_TYPE_UNION, ptempl);
break; break;
default: default:
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Declaration starts with invalid token", TokenNames[mScanner->mToken]); mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Declaration starts with invalid token", TokenNames[mScanner->mToken]);
@ -3475,7 +3478,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
return cdec; return cdec;
} }
bdec = ParseBaseTypeDeclaration(typeFlags, false); bdec = ParseBaseTypeDeclaration(typeFlags, false, ptempl);
} }
Declaration* rdec = nullptr, * ldec = nullptr; Declaration* rdec = nullptr, * ldec = nullptr;
@ -4583,7 +4586,31 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
if (dec) if (dec)
{ {
if (dec->mTemplate && mScanner->mToken == TK_LESS_THAN) if (dec->mTemplate && mScanner->mToken == TK_LESS_THAN)
{
dec = ParseTemplateExpansion(dec->mTemplate, nullptr); dec = ParseTemplateExpansion(dec->mTemplate, nullptr);
while (ConsumeTokenIf(TK_COLCOLON))
{
if (mScanner->mToken == TK_IDENT)
{
if (dec->mType == DT_NAMESPACE || dec->mType == DT_TYPE_STRUCT)
{
Declaration* ndec = dec->mScope->Lookup(mScanner->mTokenIdent, SLEVEL_USING);
if (ndec)
dec = ndec;
else
mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown identifier", mScanner->mTokenIdent);
}
else
mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Not a class or namespace");
}
else
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Identifier expected");
mScanner->NextToken();
}
}
if (dec->mType == DT_CONST_INTEGER || dec->mType == DT_CONST_FLOAT || dec->mType == DT_CONST_FUNCTION || dec->mType == DT_CONST_ASSEMBLER || dec->mType == DT_LABEL || dec->mType == DT_LABEL_REF) if (dec->mType == DT_CONST_INTEGER || dec->mType == DT_CONST_FLOAT || dec->mType == DT_CONST_FUNCTION || dec->mType == DT_CONST_ASSEMBLER || dec->mType == DT_LABEL || dec->mType == DT_LABEL_REF)
{ {
@ -4630,6 +4657,12 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
exp->mDecType = exp->mDecType->BuildReference(mScanner->mLocation); exp->mDecType = exp->mDecType->BuildReference(mScanner->mLocation);
} }
} }
else if (dec->mType == DT_CONST_TEMPLATE)
{
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
exp->mDecValue = dec;
exp->mDecType = TheSignedIntTypeDeclaration;
}
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);
@ -5617,6 +5650,19 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
else if (mScanner->mToken == TK_ARROW) else if (mScanner->mToken == TK_ARROW)
{ {
mScanner->NextToken(); mScanner->NextToken();
while (exp->mDecType->mType != DT_TYPE_POINTER)
{
Expression* dexp = new Expression(mScanner->mLocation, EX_PREFIX);
dexp->mToken = TK_ARROW;
dexp->mDecType = TheVoidPointerTypeDeclaration;
dexp->mLeft = exp;
Expression* oexp = CheckOperatorOverload(dexp);
if (oexp == dexp)
break;
exp = oexp;
}
if (exp->mDecType->mType == DT_TYPE_POINTER) if (exp->mDecType->mType == DT_TYPE_POINTER)
{ {
Expression * dexp = new Expression(mScanner->mLocation, EX_PREFIX); Expression * dexp = new Expression(mScanner->mLocation, EX_PREFIX);
@ -6713,6 +6759,9 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
case TK_BINARY_NOT: case TK_BINARY_NOT:
opident = Ident::Unique("operator~"); opident = Ident::Unique("operator~");
break; break;
case TK_ARROW:
opident = Ident::Unique("operator->");
break;
} }
if (opident) if (opident)
@ -7447,7 +7496,7 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
} }
else else
{ {
if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_INTEGER) if (exp->mType == EX_CONSTANT && (exp->mDecValue->mType == DT_CONST_INTEGER || exp->mDecValue->mType == DT_CONST_TEMPLATE))
epdec->mBase = exp->mDecValue; epdec->mBase = exp->mDecValue;
else else
mErrors->Error(exp->mLocation, EERR_TEMPLATE_PARAMS, "Const integer parameter expected", pdec->mIdent); mErrors->Error(exp->mLocation, EERR_TEMPLATE_PARAMS, "Const integer parameter expected", pdec->mIdent);
@ -7480,7 +7529,7 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
else else
{ {
Declaration* epdec = tdec->mParams; Declaration* epdec = tdec->mParams;
while (epdec && epdec->mBase->mType != DT_TYPE_TEMPLATE) while (epdec && epdec->mBase->mType != DT_TYPE_TEMPLATE && epdec->mBase->mType != DT_CONST_TEMPLATE)
epdec = epdec->mNext; epdec = epdec->mNext;
if (epdec) if (epdec)
@ -7490,6 +7539,7 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
tdec->mBase = bdec; tdec->mBase = bdec;
bdec->mTemplate = tdec; bdec->mTemplate = tdec;
bdec->mBase = tmpld->mBase; bdec->mBase = tmpld->mBase;
tdec->mNext = tmpld;
return bdec; return bdec;
} }

View File

@ -57,9 +57,9 @@ protected:
Expression * AddFunctionCallRefReturned(Expression * exp); Expression * AddFunctionCallRefReturned(Expression * exp);
Expression* CleanupExpression(Expression* exp); Expression* CleanupExpression(Expression* exp);
Declaration* ParseBaseTypeDeclaration(uint64 flags, bool qualified); Declaration* ParseBaseTypeDeclaration(uint64 flags, bool qualified, Declaration* ptempl = nullptr);
Declaration* ParseDeclaration(Declaration* pdec, bool variable, bool expression, Declaration * pthis = nullptr, Declaration * ptempl = nullptr); Declaration* ParseDeclaration(Declaration* pdec, bool variable, bool expression, Declaration * pthis = nullptr, Declaration * ptempl = nullptr);
Declaration* ParseStructDeclaration(uint64 flags, DecType dt); Declaration* ParseStructDeclaration(uint64 flags, DecType dt, Declaration* ptempl = nullptr);
Declaration* CopyConstantInitializer(int offset, Declaration* dtype, Expression* exp); Declaration* CopyConstantInitializer(int offset, Declaration* dtype, Expression* exp);
Expression* ParseInitExpression(Declaration* dtype); Expression* ParseInitExpression(Declaration* dtype);

View File

@ -1623,6 +1623,10 @@ void Scanner::NextRawToken(void)
mTokenIdent = Ident::Unique("operator[]"); mTokenIdent = Ident::Unique("operator[]");
break; break;
case TK_ARROW:
mTokenIdent = Ident::Unique("operator->");
break;
default: default:
// dirty little hack to implement token preview, got to fix // dirty little hack to implement token preview, got to fix
// this with an infinit preview sequence at one point // this with an infinit preview sequence at one point