More template support

This commit is contained in:
drmortalwombat 2023-08-17 14:55:43 +02:00
parent b7daafcac8
commit 0440f0ef19
12 changed files with 218 additions and 33 deletions

View File

@ -253,10 +253,11 @@ void ostream::numput(unsigned n, char sign)
if (mFlags & uppercase) if (mFlags & uppercase)
o = 'A' - 10; o = 'A' - 10;
while (n) unsigned nt = n;
while (nt)
{ {
char d = n % base; char d = nt % base;
n /= base; nt /= base;
if (d < 10) if (d < 10)
d += '0'; d += '0';
@ -289,10 +290,11 @@ void ostream::numput(unsigned long n, char sign)
if (mFlags & uppercase) if (mFlags & uppercase)
o = 'A' - 10; o = 'A' - 10;
while (n) unsigned long nt = n;
while (nt)
{ {
char d = n % base; char d = nt % base;
n /= base; nt /= base;
if (d < 10) if (d < 10)
d += '0'; d += '0';

View File

@ -128,8 +128,8 @@ back_insert_iterator<CT> back_inserter (CT & c)
return back_insert_iterator<CT>(c); return back_insert_iterator<CT>(c);
} }
template <class CT, class CI> template <class CT>
insert_iterator<CT> inserter (CT & c, const CI & i) insert_iterator<CT> inserter (CT & c, const CT::iterator_type & i)
{ {
return insert_iterator<CT>(c, i); return insert_iterator<CT>(c, i);
} }

View File

@ -16,11 +16,28 @@ public:
typedef T element_type; typedef T element_type;
vector(void) : _data(nullptr), _size(0), _capacity(0) {} vector(void) : _data(nullptr), _size(0), _capacity(0) {}
vector(int n) : _data((T*)malloc(n * sizeof(T))), _size(n), _capacity(n) vector(int n) : _data((T*)malloc(n * sizeof(T))), _size(n), _capacity(n)
{ {
for(int i=0; i<n; i++) for(int i=0; i<n; i++)
new (_data + i) T; new (_data + i) T;
} }
vector(const vector & v)
: _data((T*)malloc(v._size * sizeof(T))), _size(v._size), _capacity(v._size)
{
for(int i=0; i<_size; i++)
new (_data + i)T(v._data[i]);
}
vector(vector && v)
: _data(v._data), _size(v._size), _capacity(v._capacity)
{
v._data = nullptr;
v._size = 0;
v._capacity = 0;
}
~vector(void) ~vector(void)
{ {
for(int i=0; i<_size; i++) for(int i=0; i<_size; i++)

View File

@ -183,7 +183,7 @@ void putchar(char c)
{ {
__asm { __asm {
lda c lda c
jmp putpch jsr putpch
} }
} }

View File

@ -984,6 +984,10 @@ const Ident* Declaration::MangleIdent(void)
{ {
mMangleIdent = mQualIdent->PreMangle("enum "); mMangleIdent = mQualIdent->PreMangle("enum ");
} }
else if (mType == DT_TYPE_VOID)
{
mMangleIdent = Ident::Unique("void");
}
else if (mType == DT_TEMPLATE) else if (mType == DT_TEMPLATE)
{ {
mMangleIdent = Ident::Unique("<"); mMangleIdent = Ident::Unique("<");
@ -1151,7 +1155,18 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
} }
else if (tdec->mType == DT_TYPE_TEMPLATE) else if (tdec->mType == DT_TYPE_TEMPLATE)
{ {
Declaration* pdec = mScope->Insert(tdec->mIdent, fdec); Declaration* pdec;
if (tdec->mBase)
{
pdec = mScope->Lookup(tdec->mBase->mIdent);
if (!pdec)
return false;
if (pdec->mType == DT_TYPE_STRUCT)
pdec = pdec->mScope->Lookup(tdec->mIdent);
}
else
pdec = mScope->Insert(tdec->mIdent, fdec);
if (pdec && !pdec->IsSame(fdec)) if (pdec && !pdec->IsSame(fdec))
return false; return false;

View File

@ -220,7 +220,7 @@ void GlobalAnalyzer::AutoInline(void)
{ {
pdec->mVarIndex = dec->mNumVars++; pdec->mVarIndex = dec->mNumVars++;
Expression* aexp = new Expression(pdec->mLocation, EX_ASSIGNMENT); Expression* aexp = new Expression(pdec->mLocation, EX_INITIALIZATION);
Expression* pexp = new Expression(pdec->mLocation, EX_VARIABLE); Expression* pexp = new Expression(pdec->mLocation, EX_VARIABLE);
Expression* lexp = new Expression(dec->mLocation, EX_SEQUENCE); Expression* lexp = new Expression(dec->mLocation, EX_SEQUENCE);
@ -476,6 +476,27 @@ void GlobalAnalyzer::CheckInterrupt(void)
} while (changed); } while (changed);
} }
bool GlobalAnalyzer::IsStackParam(const Declaration* pdec) const
{
if (pdec->mType == DT_TYPE_STRUCT)
{
if (pdec->mSize > 4)
return true;
if (pdec->mCopyConstructor)
{
if (!((mCompilerOptions & COPT_OPTIMIZE_INLINE) && (pdec->mCopyConstructor->mFlags & DTF_REQUEST_INLINE)))
return true;
}
if (pdec->mDestructor)
{
if (!((mCompilerOptions & COPT_OPTIMIZE_INLINE) && (pdec->mDestructor->mFlags & DTF_REQUEST_INLINE)))
return true;
}
}
return false;
}
void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec) void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec)
{ {
dec->mUseCount++; dec->mUseCount++;
@ -495,7 +516,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec)
Declaration* pdec = dec->mBase->mParams; Declaration* pdec = dec->mBase->mParams;
while (pdec) while (pdec)
{ {
if (pdec->mBase->mType == DT_TYPE_STRUCT && (pdec->mBase->mCopyConstructor || pdec->mBase->mDestructor)) if (IsStackParam(pdec->mBase))
dec->mBase->mFlags |= DTF_STACKCALL; dec->mBase->mFlags |= DTF_STACKCALL;
pdec = pdec->mNext; pdec = pdec->mNext;
} }
@ -802,7 +823,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
RegisterCall(procDec, pdec->mBase->mCopyConstructor); RegisterCall(procDec, pdec->mBase->mCopyConstructor);
} }
if (pex->mType == EX_CALL && pex->mDecType->mType == DT_TYPE_STRUCT && !(pdec && (pdec->mBase->mType == DT_TYPE_REFERENCE || pdec->mBase->mType == DT_TYPE_RVALUEREF))) if (pex->mType == EX_CALL && IsStackParam(pex->mDecType) && !(pdec && (pdec->mBase->mType == DT_TYPE_REFERENCE || pdec->mBase->mType == DT_TYPE_RVALUEREF)))
ldec->mBase->mFlags |= DTF_STACKCALL; ldec->mBase->mFlags |= DTF_STACKCALL;
if (pdec) if (pdec)

View File

@ -34,6 +34,7 @@ protected:
Declaration* Analyze(Expression* exp, Declaration* procDec, bool lhs); Declaration* Analyze(Expression* exp, Declaration* procDec, bool lhs);
bool IsStackParam(const Declaration* pdec) const;
bool MarkCycle(Declaration* rootDec, Declaration* procDec); bool MarkCycle(Declaration* rootDec, Declaration* procDec);
uint64 GetProcFlags(Declaration* to) const; uint64 GetProcFlags(Declaration* to) const;

View File

@ -11156,6 +11156,43 @@ void InterCodeBasicBlock::RemoveNonRelevantStatics(void)
} }
} }
bool InterCodeBasicBlock::RecheckOuterFrame(void)
{
if (!mVisited)
{
mVisited = true;
for (int i = 0; i < mInstructions.Size(); i++)
{
InterInstruction* ins(mInstructions[i]);
if (ins->mCode == IC_LOAD)
{
if (ins->mSrc[0].mMemory == IM_FRAME)
return true;
}
else if (ins->mCode == IC_STORE || ins->mCode == IC_LEA)
{
if (ins->mSrc[1].mMemory == IM_FRAME)
return true;
}
else if (ins->mCode == IC_CONSTANT)
{
if (ins->mConst.mType == IT_POINTER && ins->mConst.mMemory == IM_FRAME)
return true;
}
else if (ins->mCode == IC_PUSH_FRAME)
return true;
}
if (mTrueJump && mTrueJump->RecheckOuterFrame())
return true;
if (mFalseJump && mFalseJump->RecheckOuterFrame())
return true;
}
return false;
}
void InterCodeBasicBlock::CollectOuterFrame(int level, int& size, bool &inner, bool &inlineAssembler, bool &byteCodeCall) void InterCodeBasicBlock::CollectOuterFrame(int level, int& size, bool &inner, bool &inlineAssembler, bool &byteCodeCall)
{ {
int i; int i;
@ -11352,6 +11389,44 @@ bool InterCodeBasicBlock::IsEqual(const InterCodeBasicBlock* block) const
return false; return false;
} }
bool InterCodeBasicBlock::PreventsCallerStaticStack(void)
{
if (!mVisited)
{
mVisited = true;
for (int i = 0; i < mInstructions.Size(); i++)
{
InterInstruction* ins(mInstructions[i]);
if (ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE)
{
if (ins->mSrc[0].mTemp >= 0 || !ins->mSrc[0].mLinkerObject)
return false;
else if (ins->mSrc[0].mLinkerObject == mProc->mLinkerObject)
; // Simple recursion
else if (!(ins->mSrc[0].mLinkerObject->mFlags & LOBJF_STATIC_STACK))
return false;
}
else if (ins->mCode == IC_DISPATCH)
{
for (int j = 0; j < mProc->mCalledFunctions.Size(); j++)
{
if (!(mProc->mCalledFunctions[j]->mLinkerObject && (mProc->mCalledFunctions[j]->mLinkerObject->mFlags & LOBJF_STATIC_STACK)))
return false;
}
}
}
if (mTrueJump && mTrueJump->PreventsCallerStaticStack())
return true;
if (mFalseJump && mFalseJump->PreventsCallerStaticStack())
return true;
}
return false;
}
bool InterCodeBasicBlock::CheckStaticStack(void) bool InterCodeBasicBlock::CheckStaticStack(void)
{ {
if (!mVisited) if (!mVisited)
@ -11368,7 +11443,13 @@ bool InterCodeBasicBlock::CheckStaticStack(void)
return false; return false;
} }
else if (mInstructions[i]->mCode == IC_DISPATCH) else if (mInstructions[i]->mCode == IC_DISPATCH)
return false; {
for (int j = 0; j < mProc->mCalledFunctions.Size(); j++)
{
if (!(mProc->mCalledFunctions[j]->mLinkerObject && (mProc->mCalledFunctions[j]->mLinkerObject->mFlags & LOBJF_STATIC_STACK)))
return false;
}
}
} }
if (mTrueJump && !mTrueJump->CheckStaticStack()) if (mTrueJump && !mTrueJump->CheckStaticStack())
@ -12571,6 +12652,8 @@ static int FindStore(InterCodeBasicBlock* block, int pos, const InterOperand& op
op.mVarIndex == ins->mSrc[1].mVarIndex) op.mVarIndex == ins->mSrc[1].mVarIndex)
return pos; return pos;
} }
if (ins->mCode == IC_POP_FRAME && op.mMemory == IM_PARAM)
return -1;
} }
return -1; return -1;
@ -17592,6 +17675,13 @@ void InterCodeProcedure::Close(void)
mLinkerObject->mFlags |= LOBJF_STATIC_STACK; mLinkerObject->mFlags |= LOBJF_STATIC_STACK;
} }
if (!(mLinkerObject->mFlags & LOBJF_STATIC_STACK))
{
ResetVisited();
if (!mEntryBlock->PreventsCallerStaticStack())
mLinkerObject->mFlags |= LOBJF_STATIC_STACK;
}
if (!mEntryBlock->mTrueJump) if (!mEntryBlock->mTrueJump)
{ {
int nconst = 0, nvariables = 0, nparams = 0, ncalls = 0, nret = 0, nother = 0, nops = 0; int nconst = 0, nvariables = 0, nparams = 0, ncalls = 0, nret = 0, nother = 0, nops = 0;
@ -17668,7 +17758,14 @@ void InterCodeProcedure::Close(void)
mLoadsIndirect = false; mLoadsIndirect = false;
mReferencedGlobals.Reset(mModule->mGlobalVars.Size()); mReferencedGlobals.Reset(mModule->mGlobalVars.Size());
mModifiedGlobals.Reset(mModule->mGlobalVars.Size()); mModifiedGlobals.Reset(mModule->mGlobalVars.Size());
#if 1
if (!mLeafProcedure && mCommonFrameSize > 0)
{
ResetVisited();
if (!mEntryBlock->RecheckOuterFrame())
mCommonFrameSize = 0;
}
#endif
ResetVisited(); ResetVisited();
mEntryBlock->CollectGlobalReferences(mReferencedGlobals, mModifiedGlobals, mStoresIndirect, mLoadsIndirect, mGlobalsChecked); mEntryBlock->CollectGlobalReferences(mReferencedGlobals, mModifiedGlobals, mStoresIndirect, mLoadsIndirect, mGlobalsChecked);
} }

View File

@ -60,16 +60,16 @@ extern int InterTypeSize[];
enum InterMemory enum InterMemory
{ {
IM_NONE, IM_NONE,
IM_PARAM, IM_PARAM, // Memory used to access parameters on stack
IM_LOCAL, IM_LOCAL,
IM_GLOBAL, IM_GLOBAL,
IM_FRAME, IM_FRAME, // Memory used to pass parameters on stack
IM_PROCEDURE, IM_PROCEDURE,
IM_INDIRECT, IM_INDIRECT,
IM_TEMPORARY, IM_TEMPORARY,
IM_ABSOLUTE, IM_ABSOLUTE,
IM_FPARAM, IM_FPARAM, // Memory used to access parameters in zp
IM_FFRAME, IM_FFRAME, // Memory used to pass parameters in zp
}; };
enum InterOperator enum InterOperator
@ -488,8 +488,10 @@ public:
void MapVariables(GrowingVariableArray& globalVars, GrowingVariableArray& localVars); void MapVariables(GrowingVariableArray& globalVars, GrowingVariableArray& localVars);
void CollectOuterFrame(int level, int& size, bool& inner, bool& inlineAssembler, bool& byteCodeCall); void CollectOuterFrame(int level, int& size, bool& inner, bool& inlineAssembler, bool& byteCodeCall);
bool RecheckOuterFrame(void);
bool IsLeafProcedure(void); bool IsLeafProcedure(void);
bool PreventsCallerStaticStack(void);
bool ForwardDiamondMovedTemp(void); bool ForwardDiamondMovedTemp(void);
bool ForwardLoopMovedTemp(void); bool ForwardLoopMovedTemp(void);

View File

@ -1018,7 +1018,10 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
ExValue vp(pdec ? pdec->mBase : TheSignedIntTypeDeclaration, ains->mDst.mTemp, 1); ExValue vp(pdec ? pdec->mBase : TheSignedIntTypeDeclaration, ains->mDst.mTemp, 1);
vr = TranslateExpression(procType, proc, block, texp, destack, breakBlock, continueBlock, inlineMapper, &vp); if (pdec && (pdec->mBase->mType == DT_TYPE_STRUCT || pdec->mBase->mType == DT_TYPE_UNION))
vr = TranslateExpression(procType, proc, block, texp, destack, breakBlock, continueBlock, inlineMapper, &vp);
else
vr = TranslateExpression(procType, proc, block, texp, destack, breakBlock, continueBlock, inlineMapper, nullptr);
if (!(pdec && pdec->mBase->IsReference()) && (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION)) if (!(pdec && pdec->mBase->IsReference()) && (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION))
{ {
@ -1056,6 +1059,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
vr = Dereference(proc, texp, block, vr, 1); vr = Dereference(proc, texp, block, vr, 1);
else if (pdec && (pdec->mBase->IsReference() && !vr.mType->IsReference())) else if (pdec && (pdec->mBase->IsReference() && !vr.mType->IsReference()))
vr = Dereference(proc, texp, block, vr, 1); vr = Dereference(proc, texp, block, vr, 1);
else if (vr.mType->IsReference() && !(pdec && pdec->mBase->IsReference()))
{
vr.mReference++;
vr = Dereference(proc, texp, block, vr);
}
else else
vr = Dereference(proc, texp, block, vr); vr = Dereference(proc, texp, block, vr);
@ -4710,8 +4718,8 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
{ {
InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mQualIdent, mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_BYTE_CODE, dec->mAlignment)); InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mQualIdent, mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_BYTE_CODE, dec->mAlignment));
#if 0 #if 1
if (proc->mIdent && !strcmp(proc->mIdent->mString, "opp::insert_iterator<struct opp::list<i16>>::+insert_iterator")) if (proc->mIdent && !strcmp(proc->mIdent->mString, "dividers"))
exp->Dump(0); exp->Dump(0);
#endif #endif
#if 0 #if 0

View File

@ -40784,7 +40784,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{ {
mInterProc = proc; mInterProc = proc;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "main"); CheckFunc = !strcmp(mInterProc->mIdent->mString, "dump<struct opp::list<i16>>");
int nblocks = proc->mBlocks.Size(); int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks]; tblocks = new NativeCodeBasicBlock * [nblocks];

View File

@ -612,12 +612,22 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified)
else else
mScanner->NextToken(); mScanner->NextToken();
while (qualified && dec && (dec->mType == DT_TYPE_STRUCT || dec->mType == DT_NAMESPACE) && ConsumeTokenIf(TK_COLCOLON)) while (qualified && dec && (dec->mType == DT_TYPE_STRUCT || dec->mType == DT_NAMESPACE || dec->mType == DT_TYPE_TEMPLATE) && ConsumeTokenIf(TK_COLCOLON))
{ {
if (ExpectToken(TK_IDENT)) if (ExpectToken(TK_IDENT))
{ {
pident = mScanner->mTokenIdent; pident = mScanner->mTokenIdent;
dec = dec->mScope->Lookup(mScanner->mTokenIdent); if (dec->mType == DT_TYPE_TEMPLATE)
{
Declaration* ndec = new Declaration(mScanner->mLocation, DT_TYPE_TEMPLATE);
ndec->mFlags |= DTF_DEFINED;
ndec->mBase = dec;
ndec->mIdent = mScanner->mTokenIdent;
dec = ndec;
}
else
dec = dec->mScope->Lookup(mScanner->mTokenIdent);
mScanner->NextToken(); mScanner->NextToken();
} }
} }
@ -1851,6 +1861,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
bool simpleDestructor = true, simpleAssignment = true, simpleConstructor = true, simpleCopy = true; bool simpleDestructor = true, simpleAssignment = true, simpleConstructor = true, simpleCopy = true;
bool inlineDestructor = true; bool inlineDestructor = true;
bool inlineConstructor = true; bool inlineConstructor = true;
bool inlineCopy = true;
const Ident* dtorident = pthis->mBase->mIdent->PreMangle("~");; const Ident* dtorident = pthis->mBase->mIdent->PreMangle("~");;
@ -1904,7 +1915,11 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
inlineConstructor = false; inlineConstructor = false;
} }
if (bcdec->mBase->mCopyConstructor) if (bcdec->mBase->mCopyConstructor)
{
simpleCopy = false; simpleCopy = false;
if (!(bcdec->mBase->mCopyConstructor->mBase->mFlags & DTF_REQUEST_INLINE))
inlineCopy = false;
}
if (bcdec->mBase->mCopyAssignment) if (bcdec->mBase->mCopyAssignment)
simpleAssignment = false; simpleAssignment = false;
bcdec = bcdec->mNext; bcdec = bcdec->mNext;
@ -2061,6 +2076,8 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
cdec->mBase = ctdec; cdec->mBase = ctdec;
cdec->mFlags |= cdec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE); cdec->mFlags |= cdec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE);
if (inlineCopy)
cdec->mFlags |= DTF_REQUEST_INLINE;
cdec->mSection = mCodeSection; cdec->mSection = mCodeSection;
@ -2254,7 +2271,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
Expression* thisexp = new Expression(mScanner->mLocation, EX_PREFIX); Expression* thisexp = new Expression(mScanner->mLocation, EX_PREFIX);
thisexp->mToken = TK_MUL; thisexp->mToken = TK_MUL;
thisexp->mDecType = pthis->mBase; thisexp->mDecType = pthis->mBase->ToMutableType();
thisexp->mLeft = pthisexp; thisexp->mLeft = pthisexp;
cdec->mValue = new Expression(mScanner->mLocation, EX_RETURN); cdec->mValue = new Expression(mScanner->mLocation, EX_RETURN);
@ -4547,6 +4564,8 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
dexp->mDecType = texp->mDecType->mBase; dexp->mDecType = texp->mDecType->mBase;
dexp->mLeft = texp; dexp->mLeft = texp;
dexp = dexp->ConstantFold(mErrors);
exp = ParseQualify(dexp); exp = ParseQualify(dexp);
} }
else else
@ -4742,6 +4761,8 @@ Expression* Parser::ParseQualify(Expression* exp)
{ {
Declaration* dtype = exp->mDecType; Declaration* dtype = exp->mDecType;
exp = exp->ConstantFold(mErrors);
if (dtype->mType == DT_TYPE_REFERENCE || dtype->mType == DT_TYPE_RVALUEREF) if (dtype->mType == DT_TYPE_REFERENCE || dtype->mType == DT_TYPE_RVALUEREF)
dtype = dtype->mBase; dtype = dtype->mBase;
@ -6403,7 +6424,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
texp->mDecType->mSize = 2; texp->mDecType->mSize = 2;
Expression* lexp = new Expression(nexp->mLocation, EX_LIST); Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
lexp->mLeft = texp; lexp->mLeft = texp->ConstantFold(mErrors);
lexp->mRight = nexp->mRight; lexp->mRight = nexp->mRight;
nexp->mRight = lexp; nexp->mRight = lexp;
@ -6446,7 +6467,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
texp->mDecType->mSize = 2; texp->mDecType->mSize = 2;
Expression* lexp = new Expression(nexp->mLocation, EX_LIST); Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
lexp->mLeft = texp; lexp->mLeft = texp->ConstantFold(mErrors);
lexp->mRight = nexp->mRight; lexp->mRight = nexp->mRight;
nexp->mRight = lexp; nexp->mRight = lexp;
@ -6495,7 +6516,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
texp->mDecType->mBase = exp->mLeft->mDecType; texp->mDecType->mBase = exp->mLeft->mDecType;
texp->mDecType->mSize = 2; texp->mDecType->mSize = 2;
nexp->mRight = texp; nexp->mRight = texp->ConstantFold(mErrors);
nexp = ResolveOverloadCall(nexp); nexp = ResolveOverloadCall(nexp);
nexp->mDecType = nexp->mLeft->mDecType->mBase; nexp->mDecType = nexp->mLeft->mDecType->mBase;
@ -6544,7 +6565,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
texp->mDecType->mSize = 2; texp->mDecType->mSize = 2;
Expression* lexp = new Expression(nexp->mLocation, EX_LIST); Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
lexp->mLeft = texp; lexp->mLeft = texp->ConstantFold(mErrors);
lexp->mRight = new Expression(nexp->mLocation, EX_CONSTANT); lexp->mRight = new Expression(nexp->mLocation, EX_CONSTANT);
lexp->mRight->mDecType = TheSignedIntTypeDeclaration; lexp->mRight->mDecType = TheSignedIntTypeDeclaration;
lexp->mRight->mDecValue = new Declaration(nexp->mLocation, DT_CONST_INTEGER); lexp->mRight->mDecValue = new Declaration(nexp->mLocation, DT_CONST_INTEGER);
@ -6660,7 +6681,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
texp->mDecType->mSize = 2; texp->mDecType->mSize = 2;
Expression* lexp = new Expression(nexp->mLocation, EX_LIST); Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
lexp->mLeft = texp; lexp->mLeft = texp->ConstantFold(mErrors);
lexp->mRight = nexp->mRight; lexp->mRight = nexp->mRight;
nexp->mRight = lexp; nexp->mRight = lexp;
@ -6719,7 +6740,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
texp->mDecType->mBase = tdec; texp->mDecType->mBase = tdec;
texp->mDecType->mSize = 2; texp->mDecType->mSize = 2;
nexp->mRight = texp; nexp->mRight = texp->ConstantFold(mErrors);
nexp = ResolveOverloadCall(nexp); nexp = ResolveOverloadCall(nexp);
nexp->mDecType = nexp->mLeft->mDecType->mBase; nexp->mDecType = nexp->mLeft->mDecType->mBase;
@ -6758,7 +6779,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
texp->mDecType->mBase = tdec; texp->mDecType->mBase = tdec;
texp->mDecType->mSize = 2; texp->mDecType->mSize = 2;
nexp->mRight = texp; nexp->mRight = texp->ConstantFold(mErrors);
nexp = ResolveOverloadCall(nexp); nexp = ResolveOverloadCall(nexp);
nexp->mDecType = nexp->mLeft->mDecType->mBase; nexp->mDecType = nexp->mLeft->mDecType->mBase;
@ -7614,6 +7635,7 @@ void Parser::ParseTemplateDeclaration(void)
{ {
bdec->mIdent = mScanner->mTokenIdent; bdec->mIdent = mScanner->mTokenIdent;
bdec->mQualIdent = mScope->Mangle(mScanner->mTokenIdent); bdec->mQualIdent = mScope->Mangle(mScanner->mTokenIdent);
bdec->mScope = new DeclarationScope(nullptr, SLEVEL_CLASS, bdec->mQualIdent);
while (mScanner->mToken != TK_SEMICOLON && mScanner->mToken != TK_OPEN_BRACE) while (mScanner->mToken != TK_SEMICOLON && mScanner->mToken != TK_OPEN_BRACE)
mScanner->NextToken(); mScanner->NextToken();