Add pure virtual functions

This commit is contained in:
drmortalwombat 2024-05-23 21:15:47 +02:00
parent 9fa8b644a7
commit a22dfa6ba7
3 changed files with 44 additions and 9 deletions

View File

@ -101,6 +101,7 @@ static const uint64 DTF_CONSTEXPR = (1ULL << 31);
static const uint64 DTF_AUTO_TEMPLATE = (1ULL << 32); static const uint64 DTF_AUTO_TEMPLATE = (1ULL << 32);
static const uint64 DTF_BANK_INLAY = (1ULL << 33); static const uint64 DTF_BANK_INLAY = (1ULL << 33);
static const uint64 DTF_PURE_VIRTUAL = (1ULL << 34);
static const uint64 DTF_FUNC_VARIABLE = (1ULL << 36); static const uint64 DTF_FUNC_VARIABLE = (1ULL << 36);
static const uint64 DTF_FUNC_ASSEMBLER = (1ULL << 37); static const uint64 DTF_FUNC_ASSEMBLER = (1ULL << 37);

View File

@ -97,6 +97,7 @@ enum ErrorID
EERR_INVALID_CAPTURE, EERR_INVALID_CAPTURE,
EERR_INVALID_PACK_USAGE, EERR_INVALID_PACK_USAGE,
EERR_INVALID_FOLD_EXPRESSION, EERR_INVALID_FOLD_EXPRESSION,
ERRR_INSTANTIATE_ABSTRACT_CLASS,
EERR_INVALID_CONSTEXPR, EERR_INVALID_CONSTEXPR,
EERR_DOUBLE_FREE, EERR_DOUBLE_FREE,

View File

@ -567,6 +567,9 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
{ {
if (mdec->mBase->mFlags & DTF_VIRTUAL) if (mdec->mBase->mFlags & DTF_VIRTUAL)
{ {
if (mdec->mFlags & DTF_PURE_VIRTUAL)
dec->mFlags |= DTF_PURE_VIRTUAL;
Declaration* vpdec = vdec; Declaration* vpdec = vdec;
Declaration* vmdec; Declaration* vmdec;
if (mdec->mIdent->mString[0] == '~') if (mdec->mIdent->mString[0] == '~')
@ -2010,6 +2013,9 @@ void Parser::PrependMemberConstructor(Declaration* pthis, Declaration* cfunc)
while (bdec->mType == DT_TYPE_ARRAY) while (bdec->mType == DT_TYPE_ARRAY)
bdec = bdec->mBase; bdec = bdec->mBase;
if (bdec->mFlags & DTF_PURE_VIRTUAL)
mErrors->Error(dec->mLocation, ERRR_INSTANTIATE_ABSTRACT_CLASS, "Cannot instantiate abstract class", dec->mIdent);
if (bdec->mType == DT_TYPE_STRUCT && bdec->mDefaultConstructor || dec->mValue) if (bdec->mType == DT_TYPE_STRUCT && bdec->mDefaultConstructor || dec->mValue)
{ {
Expression* qexp = new Expression(pthis->mLocation, EX_QUALIFY); Expression* qexp = new Expression(pthis->mLocation, EX_QUALIFY);
@ -2310,6 +2316,9 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
while (bdec->mType == DT_TYPE_ARRAY) while (bdec->mType == DT_TYPE_ARRAY)
bdec = bdec->mBase; bdec = bdec->mBase;
if (bdec->mFlags & DTF_PURE_VIRTUAL)
mErrors->Error(dec->mLocation, ERRR_INSTANTIATE_ABSTRACT_CLASS, "Cannot instantiate abstract class", dec->mIdent);
if (bdec->mType == DT_TYPE_STRUCT) if (bdec->mType == DT_TYPE_STRUCT)
{ {
if (bdec->mDestructor) if (bdec->mDestructor)
@ -3653,6 +3662,9 @@ void Parser::ParseVariableInit(Declaration* ndec)
Declaration* fcons = ndec->mBase->mScope ? ndec->mBase->mScope->Lookup(ndec->mBase->mIdent->PreMangle("+"), SLEVEL_CLASS) : nullptr; Declaration* fcons = ndec->mBase->mScope ? ndec->mBase->mScope->Lookup(ndec->mBase->mIdent->PreMangle("+"), SLEVEL_CLASS) : nullptr;
if (ndec->mBase->mFlags & DTF_PURE_VIRTUAL)
mErrors->Error(ndec->mLocation, ERRR_INSTANTIATE_ABSTRACT_CLASS, "Cannot instantiate abstract class", ndec->mIdent);
if (fcons) if (fcons)
{ {
Declaration* mtype = ndec->mBase->ToMutableType(); Declaration* mtype = ndec->mBase->ToMutableType();
@ -4595,6 +4607,20 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
} }
if (ConsumeTokenIf(TK_ASSIGN)) if (ConsumeTokenIf(TK_ASSIGN))
{
if (pthis && ndec->mBase->mType == DT_TYPE_FUNCTION && mScanner->mToken == TK_INTEGER && mScanner->mTokenInteger == 0)
{
mScanner->NextToken();
ndec->mValue = new Expression(mScanner->mLocation, EX_ASSUME);
Declaration * fdec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
fdec->mBase = TheBoolTypeDeclaration;
fdec->mInteger = 0;
ndec->mValue->mLeft = new Expression(mScanner->mLocation, EX_CONSTANT);
ndec->mValue->mLeft->mDecValue = fdec;
ndec->mValue->mLeft->mDecType = fdec->mBase;
ndec->mFlags |= DTF_DEFINED | DTF_PURE_VIRTUAL;
}
else
{ {
ndec->mValue = ParseInitExpression(ndec->mBase); ndec->mValue = ParseInitExpression(ndec->mBase);
ndec->mBase = ndec->mBase->DeduceAuto(ndec->mValue->mDecType); ndec->mBase = ndec->mBase->DeduceAuto(ndec->mValue->mDecType);
@ -4608,6 +4634,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
} }
ndec->mSize = ndec->mBase->mSize; ndec->mSize = ndec->mBase->mSize;
} }
}
else if (mScanner->mToken == TK_OPEN_PARENTHESIS && (mCompilerOptions & COPT_CPLUSPLUS)) else if (mScanner->mToken == TK_OPEN_PARENTHESIS && (mCompilerOptions & COPT_CPLUSPLUS))
{ {
ParseVariableInit(ndec); ParseVariableInit(ndec);
@ -4620,6 +4647,9 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
while (bdec && bdec->mType == DT_TYPE_ARRAY) while (bdec && bdec->mType == DT_TYPE_ARRAY)
bdec = bdec->mBase; bdec = bdec->mBase;
if (bdec->mFlags & DTF_PURE_VIRTUAL)
mErrors->Error(ndec->mLocation, ERRR_INSTANTIATE_ABSTRACT_CLASS, "Cannot instantiate abstract class", ndec->mIdent);
if (bdec && bdec->mDefaultConstructor) if (bdec && bdec->mDefaultConstructor)
{ {
bdec = bdec->ToMutableType(); bdec = bdec->ToMutableType();
@ -6926,6 +6956,9 @@ Expression* Parser::ParseNewOperator(void)
Declaration* dec = ParseBaseTypeDeclaration(0, true); Declaration* dec = ParseBaseTypeDeclaration(0, true);
if (dec->mFlags & DTF_PURE_VIRTUAL)
mErrors->Error(dec->mLocation, ERRR_INSTANTIATE_ABSTRACT_CLASS, "Cannot instantiate abstract class", dec->mIdent);
Declaration* sconst = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); Declaration* sconst = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
sconst->mBase = TheUnsignedIntTypeDeclaration; sconst->mBase = TheUnsignedIntTypeDeclaration;
sconst->mInteger = dec->mSize; sconst->mInteger = dec->mSize;