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>
|
template<class II, class OI>
|
||||||
OI copy(II first, II last, OI result)
|
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>
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue