Mangling function types in template expansion
This commit is contained in:
parent
3a9cd85072
commit
8dc37e9ab2
|
@ -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>
|
||||
OI copy(II first, II last, OI result)
|
||||
{
|
||||
|
|
|
@ -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
|
|
@ -5,17 +5,23 @@ namespace opp
|
|||
{
|
||||
|
||||
template <class T>
|
||||
class listnode
|
||||
class listhead
|
||||
{
|
||||
public:
|
||||
listnode * succ, * pred;
|
||||
T data;
|
||||
listnode<T> * succ, * pred;
|
||||
|
||||
listnode()
|
||||
listhead()
|
||||
{
|
||||
succ = this;
|
||||
pred = this;
|
||||
succ = (listnode<T> *)this;
|
||||
pred = (listnode<T> *)this;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class listnode : public listhead<T>
|
||||
{
|
||||
public:
|
||||
T data;
|
||||
|
||||
listnode(const T & t) : data(t) {}
|
||||
listnode(T && t) : data(t) {}
|
||||
|
@ -41,6 +47,11 @@ public:
|
|||
return node->data;
|
||||
}
|
||||
|
||||
T * operator->()
|
||||
{
|
||||
return &(node->data);
|
||||
}
|
||||
|
||||
list_iterator & operator++(void)
|
||||
{
|
||||
node = node->succ;
|
||||
|
@ -98,7 +109,8 @@ template <class T>
|
|||
class list
|
||||
{
|
||||
private:
|
||||
listnode<T> node;
|
||||
typedef listnode<T> ln;
|
||||
listhead<T> head;
|
||||
public:
|
||||
typedef T element_type;
|
||||
typedef list_iterator<T> iterator_type;
|
||||
|
@ -108,8 +120,8 @@ public:
|
|||
|
||||
~list(void)
|
||||
{
|
||||
listnode<T> * n = node.succ;
|
||||
while (n != &node)
|
||||
listnode<T> * n = head.succ;
|
||||
while (n != &head)
|
||||
{
|
||||
listnode<T> * m = n->succ;
|
||||
delete n;
|
||||
|
@ -119,32 +131,32 @@ public:
|
|||
|
||||
list_iterator<T> begin(void)
|
||||
{
|
||||
return list_iterator<T>(node.succ);
|
||||
return list_iterator<T>(head.succ);
|
||||
}
|
||||
|
||||
list_iterator<T> end(void)
|
||||
{
|
||||
return list_iterator<T>(&node);
|
||||
return list_iterator<T>((listnode<T> *)&head);
|
||||
}
|
||||
|
||||
T & front(void)
|
||||
{
|
||||
return node.succ->data;
|
||||
return head.succ->data;
|
||||
}
|
||||
|
||||
const T & front(void) const
|
||||
{
|
||||
return node.succ->data;
|
||||
return head.succ->data;
|
||||
}
|
||||
|
||||
T & back(void)
|
||||
{
|
||||
return node.pred->data;
|
||||
return head.pred->data;
|
||||
}
|
||||
|
||||
const T & back(void) const
|
||||
{
|
||||
return node.pred->data;
|
||||
return head.pred->data;
|
||||
}
|
||||
|
||||
list_iterator<T> erase(list_iterator<T> it);
|
||||
|
@ -171,18 +183,18 @@ public:
|
|||
template <class T>
|
||||
void list<T>::pop_front(void)
|
||||
{
|
||||
listnode<T> * n = node.succ;
|
||||
node.succ = n->succ;
|
||||
n->succ->pred = &node;
|
||||
listnode<T> * n = head.succ;
|
||||
head.succ = n->succ;
|
||||
n->succ->pred = (listnode<T> *)&head;
|
||||
delete n;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void list<T>::pop_back(void)
|
||||
{
|
||||
listnode<T> * n = node.pred;
|
||||
node.pred = n->pred;
|
||||
n->pred->succ = &node;
|
||||
listnode<T> * n = head.pred;
|
||||
head.pred = n->pred;
|
||||
n->pred->succ = (listnode<T> *)&head;
|
||||
delete n;
|
||||
}
|
||||
|
||||
|
@ -190,40 +202,40 @@ template <class T>
|
|||
void list<T>::push_front(const T & t)
|
||||
{
|
||||
listnode<T> * n = new listnode<T>(t);
|
||||
n->pred = &node;
|
||||
n->succ = node.succ;
|
||||
node.succ->pred = n;
|
||||
node.succ = n;
|
||||
n->pred = (listnode<T> *)&head;
|
||||
n->succ = head.succ;
|
||||
head.succ->pred = n;
|
||||
head.succ = n;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void list<T>::push_front(T && t)
|
||||
{
|
||||
listnode<T> * n = new listnode<T>(t);
|
||||
n->pred = &node;
|
||||
n->succ = node.succ;
|
||||
node.succ->pred = n;
|
||||
node.succ = n;
|
||||
n->pred = (listnode<T> *)&head;
|
||||
n->succ = head.succ;
|
||||
head.succ->pred = n;
|
||||
head.succ = n;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void list<T>::push_back(const T & t)
|
||||
{
|
||||
listnode<T> * n = new listnode<T>(t);
|
||||
n->succ = &node;
|
||||
n->pred = node.pred;
|
||||
node.pred->succ = n;
|
||||
node.pred = n;
|
||||
n->succ = (listnode<T> *)&head;
|
||||
n->pred = head.pred;
|
||||
head.pred->succ = n;
|
||||
head.pred = n;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void list<T>::push_back(T && t)
|
||||
{
|
||||
listnode<T> * n = new listnode<T>(t);
|
||||
n->succ = &node;
|
||||
n->pred = node.pred;
|
||||
node.pred->succ = n;
|
||||
node.pred = n;
|
||||
n->succ = (listnode<T> *)&head;
|
||||
n->pred = head.pred;
|
||||
head.pred->succ = n;
|
||||
head.pred = n;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -954,6 +954,20 @@ const Ident* Declaration::MangleIdent(void)
|
|||
{
|
||||
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)
|
||||
{
|
||||
char buffer[20];
|
||||
|
@ -964,6 +978,10 @@ const Ident* Declaration::MangleIdent(void)
|
|||
{
|
||||
mMangleIdent = Ident::Unique("float");
|
||||
}
|
||||
else if (mType == DT_TYPE_BOOL)
|
||||
{
|
||||
mMangleIdent = Ident::Unique("bool");
|
||||
}
|
||||
else if (mType == DT_TYPE_REFERENCE)
|
||||
{
|
||||
mMangleIdent = mBase->MangleIdent()->PreMangle("&");
|
||||
|
@ -1172,6 +1190,36 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
|
|||
|
||||
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
|
||||
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)))
|
||||
return false;
|
||||
|
||||
if (mType == DT_TYPE_INTEGER)
|
||||
if (mType == DT_CONST_INTEGER)
|
||||
return mInteger == dec->mInteger;
|
||||
else if (mType == DT_TYPE_INTEGER)
|
||||
return true;
|
||||
else if (mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_VOID)
|
||||
return true;
|
||||
|
|
|
@ -4548,6 +4548,10 @@ void InterCodeBasicBlock::Append(InterInstruction * code)
|
|||
assert(code->mConst.mVarIndex < mProc->mModule->mGlobalVars.Size());
|
||||
assert(mProc->mModule->mGlobalVars[code->mConst.mVarIndex]);
|
||||
}
|
||||
if (code->mCode == IC_STORE)
|
||||
{
|
||||
assert(code->mSrc[1].mOperandSize > 0);
|
||||
}
|
||||
if (code->mDst.mTemp >= 0)
|
||||
assert(code->mDst.mType != IT_NONE);
|
||||
for (int i = 0; i < code->mNumOperands; i++)
|
||||
|
@ -7484,7 +7488,28 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
|
|||
if (s0 < 0)
|
||||
{
|
||||
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].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;
|
||||
case IA_CMPGS:
|
||||
|
@ -8247,6 +8272,44 @@ bool InterCodeBasicBlock::RemoveUnusedResultInstructions(void)
|
|||
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)
|
||||
{
|
||||
if (!mVisited)
|
||||
|
@ -16371,6 +16434,15 @@ void InterCodeProcedure::RemoveUnusedInstructions(void)
|
|||
} while (mEntryBlock->RemoveUnusedResultInstructions());
|
||||
}
|
||||
|
||||
void InterCodeProcedure::RemoveUnusedLocalStoreInstructions(void)
|
||||
{
|
||||
if (mCompilerOptions & COPT_OPTIMIZE_BASIC)
|
||||
{
|
||||
ResetVisited();
|
||||
mEntryBlock->RemoveUnusedLocalStoreInstructions();
|
||||
}
|
||||
}
|
||||
|
||||
void InterCodeProcedure::RemoveUnusedStoreInstructions(InterMemory paramMemory)
|
||||
{
|
||||
if (mCompilerOptions & COPT_OPTIMIZE_BASIC)
|
||||
|
@ -16849,7 +16921,7 @@ void InterCodeProcedure::Close(void)
|
|||
{
|
||||
GrowingTypeArray tstack(IT_NONE);
|
||||
|
||||
CheckFunc = !strcmp(mIdent->mString, "main");
|
||||
CheckFunc = !strcmp(mIdent->mString, "opp::sort<struct bindexlist<i16,10>::iterator,>");
|
||||
|
||||
mEntryBlock = mBlocks[0];
|
||||
|
||||
|
@ -17471,6 +17543,8 @@ void InterCodeProcedure::Close(void)
|
|||
RemoveUnusedInstructions();
|
||||
#endif
|
||||
|
||||
RemoveUnusedLocalStoreInstructions();
|
||||
|
||||
#if 1
|
||||
ResetVisited();
|
||||
|
||||
|
@ -18370,7 +18444,7 @@ void InterCodeProcedure::Disassemble(FILE* file)
|
|||
|
||||
void InterCodeProcedure::Disassemble(const char* name, bool dumpSets)
|
||||
{
|
||||
#if 0
|
||||
#if 1
|
||||
#ifdef _WIN32
|
||||
FILE* file;
|
||||
static bool initial = true;
|
||||
|
|
|
@ -422,6 +422,7 @@ public:
|
|||
void BuildCallerSaveTempSet(NumberSet& callerSaveTemps);
|
||||
void BuildConstTempSets(void);
|
||||
bool PropagateConstOperationsUp(void);
|
||||
bool RemoveUnusedLocalStoreInstructions(void);
|
||||
|
||||
void BuildLocalVariableSets(const GrowingVariableArray& localVars, const GrowingVariableArray& params, 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 SingleAssignmentForwarding(void);
|
||||
void RemoveUnusedStoreInstructions(InterMemory paramMemory);
|
||||
void RemoveUnusedLocalStoreInstructions(void);
|
||||
void MergeCommonPathInstructions(void);
|
||||
void PushSinglePathResultInstructions(void);
|
||||
void CollectVariables(InterMemory paramMemory);
|
||||
|
|
|
@ -3276,7 +3276,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
}
|
||||
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);
|
||||
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;
|
||||
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[0].mType = IT_POINTER;
|
||||
|
|
|
@ -13623,6 +13623,7 @@ bool NativeCodeBasicBlock::ForwardAXYReg(void)
|
|||
|
||||
bool xisa = false, yisa = false;
|
||||
int xoffset = -1, yoffset = -1;
|
||||
int zpx = -1, zpy = -1, zpa = -1;
|
||||
|
||||
for (int i = 0; i < mIns.Size(); i++)
|
||||
{
|
||||
|
@ -13630,32 +13631,102 @@ bool NativeCodeBasicBlock::ForwardAXYReg(void)
|
|||
{
|
||||
xisa = true;
|
||||
xoffset = i;
|
||||
zpx = zpa;
|
||||
}
|
||||
else if (mIns[i].mType == ASMIT_TXA)
|
||||
{
|
||||
xisa = true;
|
||||
yisa = false;
|
||||
xoffset = i;
|
||||
zpa = zpx;
|
||||
}
|
||||
else if (mIns[i].mType == ASMIT_TAY)
|
||||
{
|
||||
yisa = true;
|
||||
yoffset = i;
|
||||
zpy = zpa;
|
||||
}
|
||||
else if (mIns[i].mType == ASMIT_TYA)
|
||||
{
|
||||
yisa = true;
|
||||
xisa = false;
|
||||
yoffset = i;
|
||||
zpa = zpy;
|
||||
}
|
||||
else if (mIns[i].ChangesXReg())
|
||||
xisa = false;
|
||||
else if (mIns[i].ChangesYReg())
|
||||
xisa = false;
|
||||
else if (mIns[i].ChangesAccu())
|
||||
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;
|
||||
int j = i;
|
||||
while (j > 0 && !(mIns[j - 1].mLive & LIVE_CPU_REG_Y))
|
||||
{
|
||||
mIns[j - 1].mLive |= LIVE_CPU_REG_Y;
|
||||
j--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xisa = 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 &&
|
||||
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())
|
||||
|
@ -40817,7 +40915,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
|||
{
|
||||
mInterProc = proc;
|
||||
|
||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "test_pab50");
|
||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "main");
|
||||
|
||||
int nblocks = proc->mBlocks.Size();
|
||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||
|
|
|
@ -119,7 +119,7 @@ void Parser::AddMemberFunction(Declaration* dec, Declaration* 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;
|
||||
|
||||
|
@ -169,6 +169,9 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
|
|||
dec->mScope = new DeclarationScope(nullptr, SLEVEL_CLASS, dec->mQualIdent);
|
||||
}
|
||||
|
||||
if (ptempl)
|
||||
ptempl->mBase = dec;
|
||||
|
||||
if ((mCompilerOptions & COPT_CPLUSPLUS) && mScanner->mToken == TK_COLON)
|
||||
{
|
||||
mScanner->NextToken();
|
||||
|
@ -181,7 +184,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
|
|||
else if (ConsumeTokenIf(TK_PRIVATE))
|
||||
pflags |= DTF_PRIVATE | DTF_PROTECTED;
|
||||
|
||||
Declaration* pdec = ParseQualIdent();
|
||||
Declaration* pdec = ParseBaseTypeDeclaration(0, false);
|
||||
if (pdec)
|
||||
{
|
||||
if (pdec->mType == DT_TYPE_STRUCT)
|
||||
|
@ -481,7 +484,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
|
|||
return dec;
|
||||
}
|
||||
|
||||
Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified)
|
||||
Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified, Declaration* ptempl)
|
||||
{
|
||||
Declaration* dec = nullptr;
|
||||
const Ident* pident = nullptr;
|
||||
|
@ -758,13 +761,13 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified)
|
|||
break;
|
||||
}
|
||||
case TK_STRUCT:
|
||||
dec = ParseStructDeclaration(flags, DT_TYPE_STRUCT);
|
||||
dec = ParseStructDeclaration(flags, DT_TYPE_STRUCT, ptempl);
|
||||
break;
|
||||
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;
|
||||
case TK_UNION:
|
||||
dec = ParseStructDeclaration(flags, DT_TYPE_UNION);
|
||||
dec = ParseStructDeclaration(flags, DT_TYPE_UNION, ptempl);
|
||||
break;
|
||||
default:
|
||||
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;
|
||||
}
|
||||
|
||||
bdec = ParseBaseTypeDeclaration(typeFlags, false);
|
||||
bdec = ParseBaseTypeDeclaration(typeFlags, false, ptempl);
|
||||
}
|
||||
|
||||
Declaration* rdec = nullptr, * ldec = nullptr;
|
||||
|
@ -4583,7 +4586,31 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
|
|||
if (dec)
|
||||
{
|
||||
if (dec->mTemplate && mScanner->mToken == TK_LESS_THAN)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -4630,6 +4657,12 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
|
|||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
Expression * dexp = new Expression(mScanner->mLocation, EX_PREFIX);
|
||||
|
@ -6713,6 +6759,9 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
|
|||
case TK_BINARY_NOT:
|
||||
opident = Ident::Unique("operator~");
|
||||
break;
|
||||
case TK_ARROW:
|
||||
opident = Ident::Unique("operator->");
|
||||
break;
|
||||
}
|
||||
|
||||
if (opident)
|
||||
|
@ -7447,7 +7496,7 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
|||
}
|
||||
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;
|
||||
else
|
||||
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
|
||||
{
|
||||
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;
|
||||
|
||||
if (epdec)
|
||||
|
@ -7490,6 +7539,7 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
|||
tdec->mBase = bdec;
|
||||
bdec->mTemplate = tdec;
|
||||
bdec->mBase = tmpld->mBase;
|
||||
tdec->mNext = tmpld;
|
||||
|
||||
return bdec;
|
||||
}
|
||||
|
|
|
@ -57,9 +57,9 @@ protected:
|
|||
Expression * AddFunctionCallRefReturned(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* ParseStructDeclaration(uint64 flags, DecType dt);
|
||||
Declaration* ParseStructDeclaration(uint64 flags, DecType dt, Declaration* ptempl = nullptr);
|
||||
|
||||
Declaration* CopyConstantInitializer(int offset, Declaration* dtype, Expression* exp);
|
||||
Expression* ParseInitExpression(Declaration* dtype);
|
||||
|
|
|
@ -1623,6 +1623,10 @@ void Scanner::NextRawToken(void)
|
|||
mTokenIdent = Ident::Unique("operator[]");
|
||||
break;
|
||||
|
||||
case TK_ARROW:
|
||||
mTokenIdent = Ident::Unique("operator->");
|
||||
break;
|
||||
|
||||
default:
|
||||
// dirty little hack to implement token preview, got to fix
|
||||
// this with an infinit preview sequence at one point
|
||||
|
|
Loading…
Reference in New Issue