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

View File

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

View File

@ -16,11 +16,28 @@ public:
typedef T element_type;
vector(void) : _data(nullptr), _size(0), _capacity(0) {}
vector(int n) : _data((T*)malloc(n * sizeof(T))), _size(n), _capacity(n)
{
for(int i=0; i<n; i++)
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)
{
for(int i=0; i<_size; i++)

View File

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

View File

@ -984,6 +984,10 @@ const Ident* Declaration::MangleIdent(void)
{
mMangleIdent = mQualIdent->PreMangle("enum ");
}
else if (mType == DT_TYPE_VOID)
{
mMangleIdent = Ident::Unique("void");
}
else if (mType == DT_TEMPLATE)
{
mMangleIdent = Ident::Unique("<");
@ -1151,7 +1155,18 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
}
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))
return false;

View File

@ -220,7 +220,7 @@ void GlobalAnalyzer::AutoInline(void)
{
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* lexp = new Expression(dec->mLocation, EX_SEQUENCE);
@ -476,6 +476,27 @@ void GlobalAnalyzer::CheckInterrupt(void)
} 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)
{
dec->mUseCount++;
@ -495,7 +516,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec)
Declaration* pdec = dec->mBase->mParams;
while (pdec)
{
if (pdec->mBase->mType == DT_TYPE_STRUCT && (pdec->mBase->mCopyConstructor || pdec->mBase->mDestructor))
if (IsStackParam(pdec->mBase))
dec->mBase->mFlags |= DTF_STACKCALL;
pdec = pdec->mNext;
}
@ -802,7 +823,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
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;
if (pdec)

View File

@ -34,6 +34,7 @@ protected:
Declaration* Analyze(Expression* exp, Declaration* procDec, bool lhs);
bool IsStackParam(const Declaration* pdec) const;
bool MarkCycle(Declaration* rootDec, Declaration* procDec);
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)
{
int i;
@ -11352,6 +11389,44 @@ bool InterCodeBasicBlock::IsEqual(const InterCodeBasicBlock* block) const
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)
{
if (!mVisited)
@ -11368,8 +11443,14 @@ bool InterCodeBasicBlock::CheckStaticStack(void)
return false;
}
else if (mInstructions[i]->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->CheckStaticStack())
return false;
@ -12571,6 +12652,8 @@ static int FindStore(InterCodeBasicBlock* block, int pos, const InterOperand& op
op.mVarIndex == ins->mSrc[1].mVarIndex)
return pos;
}
if (ins->mCode == IC_POP_FRAME && op.mMemory == IM_PARAM)
return -1;
}
return -1;
@ -17592,6 +17675,13 @@ void InterCodeProcedure::Close(void)
mLinkerObject->mFlags |= LOBJF_STATIC_STACK;
}
if (!(mLinkerObject->mFlags & LOBJF_STATIC_STACK))
{
ResetVisited();
if (!mEntryBlock->PreventsCallerStaticStack())
mLinkerObject->mFlags |= LOBJF_STATIC_STACK;
}
if (!mEntryBlock->mTrueJump)
{
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;
mReferencedGlobals.Reset(mModule->mGlobalVars.Size());
mModifiedGlobals.Reset(mModule->mGlobalVars.Size());
#if 1
if (!mLeafProcedure && mCommonFrameSize > 0)
{
ResetVisited();
if (!mEntryBlock->RecheckOuterFrame())
mCommonFrameSize = 0;
}
#endif
ResetVisited();
mEntryBlock->CollectGlobalReferences(mReferencedGlobals, mModifiedGlobals, mStoresIndirect, mLoadsIndirect, mGlobalsChecked);
}

View File

@ -60,16 +60,16 @@ extern int InterTypeSize[];
enum InterMemory
{
IM_NONE,
IM_PARAM,
IM_PARAM, // Memory used to access parameters on stack
IM_LOCAL,
IM_GLOBAL,
IM_FRAME,
IM_FRAME, // Memory used to pass parameters on stack
IM_PROCEDURE,
IM_INDIRECT,
IM_TEMPORARY,
IM_ABSOLUTE,
IM_FPARAM,
IM_FFRAME,
IM_FPARAM, // Memory used to access parameters in zp
IM_FFRAME, // Memory used to pass parameters in zp
};
enum InterOperator
@ -488,8 +488,10 @@ public:
void MapVariables(GrowingVariableArray& globalVars, GrowingVariableArray& localVars);
void CollectOuterFrame(int level, int& size, bool& inner, bool& inlineAssembler, bool& byteCodeCall);
bool RecheckOuterFrame(void);
bool IsLeafProcedure(void);
bool PreventsCallerStaticStack(void);
bool ForwardDiamondMovedTemp(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);
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))
{
@ -1056,6 +1059,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
vr = Dereference(proc, texp, block, vr, 1);
else if (pdec && (pdec->mBase->IsReference() && !vr.mType->IsReference()))
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
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));
#if 0
if (proc->mIdent && !strcmp(proc->mIdent->mString, "opp::insert_iterator<struct opp::list<i16>>::+insert_iterator"))
#if 1
if (proc->mIdent && !strcmp(proc->mIdent->mString, "dividers"))
exp->Dump(0);
#endif
#if 0

View File

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

View File

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