Fix default constructor with classes in header file

This commit is contained in:
drmortalwombat 2023-11-20 17:03:34 +01:00
parent 6995f5a683
commit a5f4cf3252
3 changed files with 340 additions and 324 deletions

View File

@ -136,19 +136,17 @@ void test_member_assign(void)
int main(void) int main(void)
{ {
#if 0
test_local_init(); test_local_init();
test_member_init(); test_member_init();
#endif
test_member_array_init(); test_member_array_init();
#if 0
test_local_copy(); test_local_copy();
test_member_copy(); test_member_copy();
test_local_assign(); test_local_assign();
test_member_assign(); test_member_assign();
#endif
return 0; return 0;
} }

View File

@ -89,7 +89,7 @@ Declaration* Parser::FindBaseMemberFunction(Declaration* dec, Declaration* mdec)
} }
} }
void Parser::AddMemberFunction(Declaration* dec, Declaration* mdec) Declaration * Parser::AddMemberFunction(Declaration* dec, Declaration* mdec)
{ {
Declaration* pmdec = FindBaseMemberFunction(dec, mdec); Declaration* pmdec = FindBaseMemberFunction(dec, mdec);
if (pmdec) if (pmdec)
@ -116,6 +116,8 @@ void Parser::AddMemberFunction(Declaration* dec, Declaration* mdec)
if (dec->mConst) if (dec->mConst)
dec->mConst->mScope->Insert(mdec->mIdent, gdec); dec->mConst->mScope->Insert(mdec->mIdent, gdec);
if (pdec)
return pdec;
} }
else else
{ {
@ -125,6 +127,8 @@ void Parser::AddMemberFunction(Declaration* dec, Declaration* mdec)
} }
else else
dec->mScope->Insert(mdec->mIdent, mdec); dec->mScope->Insert(mdec->mIdent, mdec);
return mdec;
} }
Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaration* ptempl) Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaration* ptempl)
@ -548,6 +552,9 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
dec->mConst->mSize = dec->mSize; dec->mConst->mSize = dec->mSize;
} }
// make sure virtual destructors end up in vtable
AddDefaultConstructors(pthis);
dec->mScope->Iterate([=](const Ident* ident, Declaration* mdec) dec->mScope->Iterate([=](const Ident* ident, Declaration* mdec)
{ {
if (mdec->mType == DT_CONST_FUNCTION) if (mdec->mType == DT_CONST_FUNCTION)
@ -609,7 +616,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
} }
); );
} }
else
AddDefaultConstructors(pthis); AddDefaultConstructors(pthis);
if (pthis->mBase->mConst) if (pthis->mBase->mConst)
@ -2195,6 +2202,10 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
const Ident* dtorident = pthis->mBase->mIdent->PreMangle("~");; const Ident* dtorident = pthis->mBase->mIdent->PreMangle("~");;
const Ident* ctorident = pthis->mBase->mIdent->PreMangle("+");; const Ident* ctorident = pthis->mBase->mIdent->PreMangle("+");;
const Ident* ctorqident = pthis->mBase->mScope->Mangle(ctorident);
const Ident* cvtorident = pthis->mBase->mIdent->PreMangle("*");;
const Ident* cvtorqident = pthis->mBase->mScope->Mangle(cvtorident);
// Extract constructor and destructor from scope // Extract constructor and destructor from scope
@ -2327,8 +2338,6 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
if (mCompilerOptions & COPT_NATIVE) if (mCompilerOptions & COPT_NATIVE)
cdec->mFlags |= DTF_NATIVE; cdec->mFlags |= DTF_NATIVE;
pthis->mBase->mDestructor = cdec;
cdec->mIdent = dtorident; cdec->mIdent = dtorident;
cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent); cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent);
@ -2340,6 +2349,9 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
cdec->mFlags |= DTF_DEFINED; cdec->mFlags |= DTF_DEFINED;
cdec->mValue = new Expression(mScanner->mLocation, EX_VOID); cdec->mValue = new Expression(mScanner->mLocation, EX_VOID);
pthis->mBase->mDestructor = AddMemberFunction(pthis->mBase, cdec);
} }
} }
@ -2350,7 +2362,6 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
Declaration* ctdec = new Declaration(mScanner->mLocation, DT_TYPE_FUNCTION); Declaration* ctdec = new Declaration(mScanner->mLocation, DT_TYPE_FUNCTION);
ctdec->mSize = 0; ctdec->mSize = 0;
Declaration* pdec = nullptr;
ctdec->mBase = TheVoidTypeDeclaration; ctdec->mBase = TheVoidTypeDeclaration;
ctdec->mFlags |= DTF_DEFINED; ctdec->mFlags |= DTF_DEFINED;
@ -2358,6 +2369,8 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
Declaration* cdec = new Declaration(ctdec->mLocation, DT_CONST_FUNCTION); Declaration* cdec = new Declaration(ctdec->mLocation, DT_CONST_FUNCTION);
cdec->mBase = ctdec; cdec->mBase = ctdec;
cdec->mIdent = ctorident;
cdec->mQualIdent = ctorqident;
cdec->mFlags |= cdec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE); cdec->mFlags |= cdec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE);
if (inlineConstructor) if (inlineConstructor)
@ -2368,13 +2381,6 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
if (mCompilerOptions & COPT_NATIVE) if (mCompilerOptions & COPT_NATIVE)
cdec->mFlags |= DTF_NATIVE; cdec->mFlags |= DTF_NATIVE;
pthis->mBase->mDefaultConstructor = cdec;
cdec->mIdent = ctorident;
cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent);
AddMemberFunction(pthis->mBase, cdec);
cdec->mCompilerOptions = mCompilerOptions; cdec->mCompilerOptions = mCompilerOptions;
cdec->mBase->mCompilerOptions = mCompilerOptions; cdec->mBase->mCompilerOptions = mCompilerOptions;
@ -2383,6 +2389,8 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
cdec->mFlags |= DTF_DEFINED; cdec->mFlags |= DTF_DEFINED;
cdec->mValue = new Expression(mScanner->mLocation, EX_VOID); cdec->mValue = new Expression(mScanner->mLocation, EX_VOID);
pthis->mBase->mDefaultConstructor = AddMemberFunction(pthis->mBase, cdec);
} }
} }
@ -2424,9 +2432,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
pthis->mBase->mCopyConstructor = cdec; pthis->mBase->mCopyConstructor = cdec;
cdec->mIdent = ctorident; cdec->mIdent = ctorident;
cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent); cdec->mQualIdent = ctorqident;
AddMemberFunction(pthis->mBase, cdec);
cdec->mCompilerOptions = mCompilerOptions; cdec->mCompilerOptions = mCompilerOptions;
cdec->mBase->mCompilerOptions = mCompilerOptions; cdec->mBase->mCompilerOptions = mCompilerOptions;
@ -2452,6 +2458,9 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
cdec->mScope = new DeclarationScope(nullptr, SLEVEL_CLASS); cdec->mScope = new DeclarationScope(nullptr, SLEVEL_CLASS);
pthis->mBase->mCopyConstructor = AddMemberFunction(pthis->mBase, cdec);
if (pthis->mBase->mCopyConstructor == cdec)
{
Declaration* dec = pthis->mBase->mParams; Declaration* dec = pthis->mBase->mParams;
while (dec) while (dec)
{ {
@ -2547,6 +2556,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
dec = dec->mNext; dec = dec->mNext;
} }
}
cdec->mFlags |= DTF_DEFINED; cdec->mFlags |= DTF_DEFINED;
} }
@ -2592,13 +2602,9 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
cdec->mIdent = Ident::Unique("operator="); cdec->mIdent = Ident::Unique("operator=");
cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent); cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent);
pthis->mBase->mCopyAssignment = cdec;
cdec->mCompilerOptions = mCompilerOptions; cdec->mCompilerOptions = mCompilerOptions;
cdec->mBase->mCompilerOptions = mCompilerOptions; cdec->mBase->mCompilerOptions = mCompilerOptions;
AddMemberFunction(pthis->mBase, cdec);
cdec->mVarIndex = -1; cdec->mVarIndex = -1;
Expression* pthisexp = new Expression(pthis->mLocation, EX_VARIABLE); Expression* pthisexp = new Expression(pthis->mLocation, EX_VARIABLE);
@ -2622,6 +2628,9 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
cdec->mScope = new DeclarationScope(nullptr, SLEVEL_CLASS); cdec->mScope = new DeclarationScope(nullptr, SLEVEL_CLASS);
pthis->mBase->mCopyAssignment = AddMemberFunction(pthis->mBase, cdec);
if (pthis->mBase->mCopyAssignment == cdec)
{
Declaration* dec = pthis->mBase->mParams; Declaration* dec = pthis->mBase->mParams;
if (dec) if (dec)
{ {
@ -2719,6 +2728,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
dec = dec->mPrev; dec = dec->mPrev;
} }
} }
}
cdec->mFlags |= DTF_DEFINED; cdec->mFlags |= DTF_DEFINED;
} }
@ -2756,10 +2766,8 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
if (mCompilerOptions & COPT_NATIVE) if (mCompilerOptions & COPT_NATIVE)
cdec->mFlags |= DTF_NATIVE; cdec->mFlags |= DTF_NATIVE;
pthis->mBase->mVectorConstructor = cdec; cdec->mIdent = cvtorident;
cdec->mQualIdent = cvtorqident;
cdec->mIdent = ctorident;
cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent);
cdec->mCompilerOptions = mCompilerOptions; cdec->mCompilerOptions = mCompilerOptions;
cdec->mBase->mCompilerOptions = mCompilerOptions; cdec->mBase->mCompilerOptions = mCompilerOptions;
@ -2768,6 +2776,9 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
cdec->mFlags |= DTF_DEFINED; cdec->mFlags |= DTF_DEFINED;
pthis->mBase->mVectorConstructor = AddMemberFunction(pthis->mBase, cdec);
if (pthis->mBase->mVectorConstructor == cdec)
{
Expression* pexp = new Expression(mScanner->mLocation, EX_VARIABLE); Expression* pexp = new Expression(mScanner->mLocation, EX_VARIABLE);
pexp->mDecType = vthis; pexp->mDecType = vthis;
pexp->mDecValue = ctdec->mParams; pexp->mDecValue = ctdec->mParams;
@ -2799,6 +2810,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
cdec->mValue = wexp; cdec->mValue = wexp;
} }
}
if (pthis->mBase->mDestructor && !pthis->mBase->mVectorDestructor) if (pthis->mBase->mDestructor && !pthis->mBase->mVectorDestructor)
{ {
@ -2832,8 +2844,6 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
if (mCompilerOptions & COPT_NATIVE) if (mCompilerOptions & COPT_NATIVE)
cdec->mFlags |= DTF_NATIVE; cdec->mFlags |= DTF_NATIVE;
pthis->mBase->mVectorDestructor = cdec;
cdec->mIdent = dtorident; cdec->mIdent = dtorident;
cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent); cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent);
@ -2844,6 +2854,9 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
cdec->mFlags |= DTF_DEFINED; cdec->mFlags |= DTF_DEFINED;
pthis->mBase->mVectorDestructor = AddMemberFunction(pthis->mBase, cdec);
if (pthis->mBase->mVectorDestructor == cdec)
{
Expression* pexp = new Expression(mScanner->mLocation, EX_VARIABLE); Expression* pexp = new Expression(mScanner->mLocation, EX_VARIABLE);
pexp->mDecType = vthis; pexp->mDecType = vthis;
pexp->mDecValue = ctdec->mParams; pexp->mDecValue = ctdec->mParams;
@ -2876,6 +2889,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
cdec->mValue = wexp; cdec->mValue = wexp;
} }
}
if (pthis->mBase->mCopyConstructor && !pthis->mBase->mVectorCopyConstructor) if (pthis->mBase->mCopyConstructor && !pthis->mBase->mVectorCopyConstructor)
{ {
@ -2917,8 +2931,6 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
if (mCompilerOptions & COPT_NATIVE) if (mCompilerOptions & COPT_NATIVE)
cdec->mFlags |= DTF_NATIVE; cdec->mFlags |= DTF_NATIVE;
pthis->mBase->mVectorCopyConstructor = cdec;
cdec->mIdent = ctorident; cdec->mIdent = ctorident;
cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent); cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent);
@ -2929,6 +2941,9 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
cdec->mFlags |= DTF_DEFINED; cdec->mFlags |= DTF_DEFINED;
pthis->mBase->mVectorCopyConstructor = AddMemberFunction(pthis->mBase, cdec);
if (pthis->mBase->mVectorCopyConstructor == cdec)
{
Expression* pexp = new Expression(mScanner->mLocation, EX_VARIABLE); Expression* pexp = new Expression(mScanner->mLocation, EX_VARIABLE);
pexp->mDecType = vthis; pexp->mDecType = vthis;
pexp->mDecValue = ctdec->mParams; pexp->mDecValue = ctdec->mParams;
@ -2979,6 +2994,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
cdec->mValue = wexp; cdec->mValue = wexp;
} }
}
if (pthis->mBase->mCopyAssignment && !pthis->mBase->mVectorCopyAssignment) if (pthis->mBase->mCopyAssignment && !pthis->mBase->mVectorCopyAssignment)
{ {
@ -3020,10 +3036,8 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
if (mCompilerOptions & COPT_NATIVE) if (mCompilerOptions & COPT_NATIVE)
cdec->mFlags |= DTF_NATIVE; cdec->mFlags |= DTF_NATIVE;
pthis->mBase->mVectorCopyAssignment = cdec; cdec->mIdent = cvtorident;
cdec->mQualIdent = cvtorqident;
cdec->mIdent = ctorident;
cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent);
cdec->mCompilerOptions = mCompilerOptions; cdec->mCompilerOptions = mCompilerOptions;
cdec->mBase->mCompilerOptions = mCompilerOptions; cdec->mBase->mCompilerOptions = mCompilerOptions;
@ -3032,6 +3046,9 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
cdec->mFlags |= DTF_DEFINED; cdec->mFlags |= DTF_DEFINED;
pthis->mBase->mVectorCopyAssignment = AddMemberFunction(pthis->mBase, cdec);
if (pthis->mBase->mVectorCopyAssignment == cdec)
{
Expression* pexp = new Expression(mScanner->mLocation, EX_VARIABLE); Expression* pexp = new Expression(mScanner->mLocation, EX_VARIABLE);
pexp->mDecType = vthis; pexp->mDecType = vthis;
pexp->mDecValue = ctdec->mParams; pexp->mDecValue = ctdec->mParams;
@ -3083,6 +3100,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
cdec->mValue = wexp; cdec->mValue = wexp;
} }
} }
}
void Parser::AppendMemberDestructor(Declaration* pthis) void Parser::AppendMemberDestructor(Declaration* pthis)
{ {

View File

@ -56,7 +56,7 @@ protected:
void AddDefaultConstructors(Declaration* pthis); void AddDefaultConstructors(Declaration* pthis);
void ParseVariableInit(Declaration* ndec); void ParseVariableInit(Declaration* ndec);
void AddMemberFunction(Declaration* dec, Declaration* mdec); Declaration* AddMemberFunction(Declaration* dec, Declaration* mdec);
Declaration* FindBaseMemberFunction(Declaration* dec, Declaration* mdec); Declaration* FindBaseMemberFunction(Declaration* dec, Declaration* mdec);
Expression * AddFunctionCallRefReturned(Expression * exp); Expression * AddFunctionCallRefReturned(Expression * exp);