From 3d6b60c9f4396dcf0d89cfa035d49390d3cae3e8 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Wed, 28 Jun 2023 22:14:29 +0200 Subject: [PATCH] Implement base class constructors --- oscar64/Declaration.cpp | 100 ++++++++++++++++------- oscar64/Declaration.h | 5 +- oscar64/GlobalAnalyzer.cpp | 2 +- oscar64/InterCodeGenerator.cpp | 34 ++++---- oscar64/Parser.cpp | 141 ++++++++++++++++++++++++++++++--- oscar64/Parser.h | 2 + 6 files changed, 226 insertions(+), 58 deletions(-) diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index bd4f610..38b65d7 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -447,46 +447,46 @@ Expression* Expression::ConstantFold(Errors * errors) return ex; } #endif - else if (mType == EX_TYPECAST && mRight->mType == EX_CONSTANT) + else if (mType == EX_TYPECAST && mLeft->mType == EX_CONSTANT) { - if (mLeft->mDecType->mType == DT_TYPE_POINTER) + if (mDecType->mType == DT_TYPE_POINTER) { - if (mRight->mDecValue->mType == DT_CONST_ADDRESS || mRight->mDecValue->mType == DT_CONST_INTEGER) + if (mLeft->mDecValue->mType == DT_CONST_ADDRESS || mLeft->mDecValue->mType == DT_CONST_INTEGER) { Expression* ex = new Expression(mLocation, EX_CONSTANT); Declaration* dec = new Declaration(mLocation, DT_CONST_ADDRESS); - dec->mBase = mLeft->mDecType; - dec->mInteger = mRight->mDecValue->mInteger; + dec->mBase = mDecType; + dec->mInteger = mLeft->mDecValue->mInteger; ex->mDecValue = dec; - ex->mDecType = mLeft->mDecType; + ex->mDecType = mDecType; return ex; } - else if (mRight->mDecValue->mType == DT_CONST_FUNCTION) + else if (mLeft->mDecValue->mType == DT_CONST_FUNCTION) { Expression* ex = new Expression(mLocation, EX_CONSTANT); - ex->mDecValue = mRight->mDecValue; - ex->mDecType = mLeft->mDecType; + ex->mDecValue = mLeft->mDecValue; + ex->mDecType = mDecType; return ex; } } - else if (mLeft->mDecType->mType == DT_TYPE_INTEGER) + else if (mDecType->mType == DT_TYPE_INTEGER) { - if (mRight->mDecValue->mType == DT_CONST_FLOAT) + if (mLeft->mDecValue->mType == DT_CONST_FLOAT) { Expression* ex = new Expression(mLocation, EX_CONSTANT); Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER); - dec->mBase = mLeft->mDecType; - dec->mInteger = int64(mRight->mDecValue->mNumber); + dec->mBase = mDecType; + dec->mInteger = int64(mLeft->mDecValue->mNumber); ex->mDecValue = dec; - ex->mDecType = mLeft->mDecType; + ex->mDecType = mDecType; return ex; } - else if (mRight->mDecValue->mType == DT_CONST_INTEGER) + else if (mLeft->mDecValue->mType == DT_CONST_INTEGER) { - int64 sval = 1ULL << (8 * mLeft->mDecType->mSize); - int64 v = mRight->mDecValue->mInteger & (sval - 1); + int64 sval = 1ULL << (8 * mDecType->mSize); + int64 v = mLeft->mDecValue->mInteger & (sval - 1); - if (mLeft->mDecType->mFlags & DTF_SIGNED) + if (mDecType->mFlags & DTF_SIGNED) { if (v & (sval >> 1)) v -= sval; @@ -494,23 +494,23 @@ Expression* Expression::ConstantFold(Errors * errors) Expression* ex = new Expression(mLocation, EX_CONSTANT); Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER); - dec->mBase = mLeft->mDecType; + dec->mBase = mDecType; dec->mInteger = v; ex->mDecValue = dec; - ex->mDecType = mLeft->mDecType; + ex->mDecType = mDecType; return ex; } } - else if (mLeft->mDecType->mType == DT_TYPE_FLOAT) + else if (mDecType->mType == DT_TYPE_FLOAT) { - if (mRight->mDecValue->mType == DT_CONST_INTEGER) + if (mLeft->mDecValue->mType == DT_CONST_INTEGER) { Expression* ex = new Expression(mLocation, EX_CONSTANT); Declaration* dec = new Declaration(mLocation, DT_CONST_FLOAT); - dec->mBase = mLeft->mDecType; - dec->mNumber = double(mRight->mDecValue->mInteger); + dec->mBase = mDecType; + dec->mNumber = double(mLeft->mDecValue->mInteger); ex->mDecValue = dec; - ex->mDecType = mLeft->mDecType; + ex->mDecType = mDecType; return ex; } } @@ -781,7 +781,8 @@ Expression* Expression::ConstantFold(Errors * errors) Declaration::Declaration(const Location& loc, DecType type) : mLocation(loc), mEndLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mQualIdent(nullptr), mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0), - mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mPrev(nullptr), mConst(nullptr), + mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mPrev(nullptr), + mConst(nullptr), mMutable(nullptr), mDefaultConstructor(nullptr), mDestructor(nullptr), mCopyConstructor(nullptr), mCopyAssignment(nullptr), mVectorConstructor(nullptr), mVectorDestructor(nullptr), mVectorCopyConstructor(nullptr), mVectorCopyAssignment(nullptr), mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1), @@ -938,12 +939,49 @@ Declaration* Declaration::ToConstType(void) ndec->mParams = mParams; ndec->mIdent = mIdent; ndec->mQualIdent = mQualIdent; + + ndec->mDefaultConstructor = mDefaultConstructor; + ndec->mCopyConstructor = mCopyConstructor; + ndec->mVectorConstructor = mVectorConstructor; + ndec->mVectorCopyConstructor = mVectorCopyConstructor; + + ndec->mMutable = this; mConst = ndec; } return mConst; } +Declaration* Declaration::ToMutableType(void) +{ + if (!(mFlags & DTF_CONST)) + return this; + + if (!mMutable) + { + Declaration* ndec = new Declaration(mLocation, mType); + ndec->mSize = mSize; + ndec->mStride = mStride; + ndec->mBase = mBase; + ndec->mFlags = mFlags | DTF_CONST; + ndec->mScope = mScope; + ndec->mParams = mParams; + ndec->mIdent = mIdent; + ndec->mQualIdent = mQualIdent; + + ndec->mDefaultConstructor = mDefaultConstructor; + ndec->mCopyConstructor = mCopyConstructor; + ndec->mVectorConstructor = mVectorConstructor; + ndec->mVectorCopyConstructor = mVectorCopyConstructor; + + ndec->mConst = this; + mMutable = ndec; + } + + return mMutable; +} + + bool Declaration::IsSubType(const Declaration* dec) const { if (this == dec) @@ -978,7 +1016,15 @@ bool Declaration::IsSubType(const Declaration* dec) const return true; if (dec->mBase) - return IsSubType(dec->mBase); + { + Declaration* bcdec = dec->mBase; + while (bcdec) + { + if (IsSubType(bcdec->mBase)) + return true; + bcdec = bcdec->mNext; + } + } return false; } diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index 5139bda..3667799 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -49,6 +49,7 @@ enum DecType DT_FUNCTION_REF, DT_LABEL_REF, DT_NAMESPACE, + DT_BASECLASS }; // TypeFlags @@ -222,7 +223,7 @@ public: Location mLocation, mEndLocation; DecType mType; Token mToken; - Declaration * mBase, * mParams, * mNext, * mPrev, * mConst; + Declaration * mBase, * mParams, * mNext, * mPrev, * mConst, * mMutable; Declaration * mDefaultConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment; Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment; @@ -254,6 +255,8 @@ public: void SetDefined(void); Declaration* ToConstType(void); + Declaration* ToMutableType(void); + Declaration* ToStriped(int stripe); Declaration* ToStriped(Errors* errors); Declaration* Clone(void); diff --git a/oscar64/GlobalAnalyzer.cpp b/oscar64/GlobalAnalyzer.cpp index 4fedd33..20f2221 100644 --- a/oscar64/GlobalAnalyzer.cpp +++ b/oscar64/GlobalAnalyzer.cpp @@ -823,7 +823,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo case EX_TYPE: break; case EX_TYPECAST: - return Analyze(exp->mRight, procDec, false); + return Analyze(exp->mLeft, procDec, false); break; case EX_LOGICAL_AND: ldec = Analyze(exp->mLeft, procDec, false); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index da41554..855932f 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -3739,11 +3739,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case EX_TYPECAST: { - vr = TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper); + vr = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); InterInstruction * ins = new InterInstruction(exp->mLocation, IC_CONVERSION_OPERATOR); - if (exp->mLeft->mDecType->mType == DT_TYPE_FLOAT && vr.mType->IsIntegerType()) + if (exp->mDecType->mType == DT_TYPE_FLOAT && vr.mType->IsIntegerType()) { vr = Dereference(proc, exp, block, vr); @@ -3778,50 +3778,50 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* ins->mOperator = (vr.mType->mFlags & DTF_SIGNED) ? IA_INT2FLOAT : IA_UINT2FLOAT; ins->mSrc[0].mType = IT_INT16; ins->mSrc[0].mTemp = stemp; - ins->mDst.mType = InterTypeOf(exp->mLeft->mDecType); + ins->mDst.mType = InterTypeOf(exp->mDecType); ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType); block->Append(ins); } - else if (exp->mLeft->mDecType->IsIntegerType() && vr.mType->mType == DT_TYPE_FLOAT) + else if (exp->mDecType->IsIntegerType() && vr.mType->mType == DT_TYPE_FLOAT) { vr = Dereference(proc, exp, block, vr); - ins->mOperator = (exp->mLeft->mDecType->mFlags & DTF_SIGNED) ? IA_FLOAT2INT : IA_FLOAT2UINT; + ins->mOperator = (exp->mDecType->mFlags & DTF_SIGNED) ? IA_FLOAT2INT : IA_FLOAT2UINT; ins->mSrc[0].mType = InterTypeOf(vr.mType); ins->mSrc[0].mTemp = vr.mTemp; ins->mDst.mType = IT_INT16; ins->mDst.mTemp = proc->AddTemporary(IT_INT16); block->Append(ins); - if (exp->mLeft->mDecType->mSize == 1) + if (exp->mDecType->mSize == 1) { InterInstruction* xins = new InterInstruction(exp->mLocation, IC_TYPECAST); xins->mSrc[0].mType = IT_INT16; xins->mSrc[0].mTemp = ins->mDst.mTemp; - xins->mDst.mType = InterTypeOf(exp->mLeft->mDecType); + xins->mDst.mType = InterTypeOf(exp->mDecType); xins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType); block->Append(xins); ins = xins; } } - else if (exp->mLeft->mDecType->mType == DT_TYPE_POINTER && vr.mType->mType == DT_TYPE_POINTER) + else if (exp->mDecType->mType == DT_TYPE_POINTER && vr.mType->mType == DT_TYPE_POINTER) { // no need for actual operation when casting pointer to pointer - return ExValue(exp->mLeft->mDecType, vr.mTemp, vr.mReference); + return ExValue(exp->mDecType, vr.mTemp, vr.mReference); } - else if (exp->mLeft->mDecType->mType == DT_TYPE_POINTER && vr.mType->mType == DT_TYPE_ARRAY) + else if (exp->mDecType->mType == DT_TYPE_POINTER && vr.mType->mType == DT_TYPE_ARRAY) { // no need for actual operation when casting pointer to pointer - return ExValue(exp->mLeft->mDecType, vr.mTemp, vr.mReference - 1); + return ExValue(exp->mDecType, vr.mTemp, vr.mReference - 1); } - else if (exp->mLeft->mDecType->mType != DT_TYPE_VOID && vr.mType->mType == DT_TYPE_VOID) + else if (exp->mDecType->mType != DT_TYPE_VOID && vr.mType->mType == DT_TYPE_VOID) { mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Cannot cast void object to non void object"); - return ExValue(exp->mLeft->mDecType, vr.mTemp, vr.mReference); + return ExValue(exp->mDecType, vr.mTemp, vr.mReference); } - else if (exp->mLeft->mDecType->IsIntegerType() && vr.mType->IsIntegerType()) + else if (exp->mDecType->IsIntegerType() && vr.mType->IsIntegerType()) { vr = Dereference(proc, exp, block, vr); - return CoerceType(proc, exp, block, vr, exp->mLeft->mDecType); + return CoerceType(proc, exp, block, vr, exp->mDecType); } else { @@ -3829,12 +3829,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* ins->mCode = IC_TYPECAST; ins->mSrc[0].mType = InterTypeOf(vr.mType); ins->mSrc[0].mTemp = vr.mTemp; - ins->mDst.mType = InterTypeOf(exp->mLeft->mDecType); + ins->mDst.mType = InterTypeOf(exp->mDecType); ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType); block->Append(ins); } - return ExValue(exp->mLeft->mDecType, ins->mDst.mTemp); + return ExValue(exp->mDecType, ins->mDst.mTemp); } break; diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 79cbbaf..4718930 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -104,8 +104,12 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt) { if (pdec->mType == DT_TYPE_STRUCT) { - dec->mBase = pdec; + Declaration* bcdec = new Declaration(mScanner->mLocation, DT_BASECLASS); + bcdec->mBase = pdec; + dec->mSize = pdec->mSize; + + dec->mBase = bcdec; } else mErrors->Error(mScanner->mLocation, ERRO_NOT_A_BASE_CLASS, "Not a base class", dec->mIdent); @@ -1260,9 +1264,44 @@ void Parser::PrependMemberConstructor(Declaration* pthis, Declaration* cfunc) thisexp->mDecType = pthis->mBase; thisexp->mLeft = pthisexp; + Declaration* bcdec = pthis->mBase->mBase; + while (bcdec) + { + Declaration* mfunc = cfunc->mScope ? cfunc->mScope->Lookup(bcdec->mBase->mIdent) : nullptr; + + if (mfunc) + { + Expression* sexp = new Expression(cfunc->mLocation, EX_SEQUENCE); + sexp->mLeft = mfunc->mValue; + sexp->mRight = cfunc->mValue; + cfunc->mValue = sexp; + } + else if (bcdec->mBase->mDefaultConstructor) + { + Declaration* mdec = bcdec->mBase->mDefaultConstructor; + + Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT); + cexp->mDecValue = mdec; + cexp->mDecType = cexp->mDecValue->mBase; + + Expression * dexp = new Expression(mScanner->mLocation, EX_CALL); + dexp->mLeft = cexp; + dexp->mRight = pthisexp; + + Expression* sexp = new Expression(mScanner->mLocation, EX_SEQUENCE); + + sexp->mLeft = dexp; + sexp->mRight = cfunc->mValue; + cfunc->mValue = sexp; + } + + bcdec = bcdec->mNext; + } + Declaration* dec = pthis->mBase->mParams; if (dec) { + dec = dec->Last(); while (dec) { @@ -1387,7 +1426,28 @@ void Parser::BuildMemberConstructor(Declaration* pthis, Declaration* cfunc) if (ExpectToken(TK_IDENT)) { Declaration* dec = pthis->mBase->mScope->Lookup(mScanner->mTokenIdent); - if (dec && dec->mType == DT_ELEMENT) + + Declaration* pcdec = pthis->mBase->mBase; + while (pcdec && pcdec->mBase->mIdent != mScanner->mTokenIdent) + pcdec = pcdec->mNext; + + if (pcdec) + { + Expression* qexp = new Expression(mScanner->mLocation, EX_PREFIX); + qexp->mToken = TK_MUL; + qexp->mDecType = pcdec->mBase; + qexp->mLeft = pthisexp; + + Declaration* dec = new Declaration(mScanner->mLocation, DT_CONST_CONSTRUCTOR); + dec->mIdent = mScanner->mTokenIdent; + + mScanner->NextToken(); + + dec->mValue = BuildMemberInitializer(qexp); + + cfunc->mScope->Insert(dec->mIdent, dec); + } + else if (dec && dec->mType == DT_ELEMENT) { Expression* qexp = new Expression(pthis->mLocation, EX_QUALIFY); qexp->mLeft = thisexp; @@ -1415,7 +1475,7 @@ void Parser::BuildMemberConstructor(Declaration* pthis, Declaration* cfunc) void Parser::AddDefaultConstructors(Declaration* pthis) { - bool simpleDestructor = true, simpleAssignment = true; + bool simpleDestructor = true, simpleAssignment = true, simpleConstructor = true, simpleCopy = true; char dname[100]; strcpy_s(dname, "~"); @@ -1455,6 +1515,20 @@ void Parser::AddDefaultConstructors(Declaration* pthis) adec = adec->mNext; } + Declaration* bcdec = pthis->mBase->mBase; + while (bcdec) + { + if (bcdec->mBase->mDestructor) + simpleDestructor = false; + if (bcdec->mBase->mDefaultConstructor) + simpleConstructor = false; + if (bcdec->mBase->mCopyConstructor) + simpleCopy = false; + if (bcdec->mBase->mCopyAssignment) + simpleAssignment = false; + bcdec = bcdec->mNext; + } + Declaration* dec = pthis->mBase->mParams; while (dec) { @@ -1470,6 +1544,10 @@ void Parser::AddDefaultConstructors(Declaration* pthis) { if (bdec->mDestructor) simpleDestructor = false; + if (bdec->mDefaultConstructor) + simpleConstructor = false; + if (bdec->mCopyConstructor) + simpleCopy = false; if (bdec->mCopyAssignment) simpleAssignment = false; } @@ -1514,7 +1592,10 @@ void Parser::AddDefaultConstructors(Declaration* pthis) cdec->mValue = new Expression(mScanner->mLocation, EX_VOID); } + } + if (!simpleConstructor) + { if (!pthis->mBase->mDefaultConstructor) { Declaration* ctdec = new Declaration(mScanner->mLocation, DT_TYPE_FUNCTION); @@ -1552,7 +1633,10 @@ void Parser::AddDefaultConstructors(Declaration* pthis) cdec->mValue = new Expression(mScanner->mLocation, EX_VOID); } + } + if (!simpleCopy) + { if (!pthis->mBase->mCopyConstructor) { Declaration* ctdec = new Declaration(mScanner->mLocation, DT_TYPE_FUNCTION); @@ -2567,8 +2651,10 @@ void Parser::ParseVariableInit(Declaration* ndec) if (fcons) { + Declaration* mtype = ndec->mBase->ToMutableType(); + Expression* vexp = new Expression(mScanner->mLocation, EX_VARIABLE); - vexp->mDecType = ndec->mBase; + vexp->mDecType = mtype; vexp->mDecValue = ndec; Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT); @@ -2584,7 +2670,7 @@ void Parser::ParseVariableInit(Declaration* ndec) texp->mLeft = vexp; texp->mDecType = new Declaration(mScanner->mLocation, DT_TYPE_POINTER); texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED; - texp->mDecType->mBase = ndec->mBase; + texp->mDecType->mBase = mtype; texp->mDecType->mSize = 2; if (fexp->mRight) @@ -2793,7 +2879,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex cdec->mValue = ParseFunction(cdec->mBase); - cdec->mFlags |= DTF_DEFINED; + cdec->mFlags |= DTF_DEFINED | DTF_REQUEST_INLINE; cdec->mNumVars = mLocalIndex; } @@ -2880,7 +2966,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex cdec->mValue = ParseFunction(cdec->mBase); - cdec->mFlags |= DTF_DEFINED; + cdec->mFlags |= DTF_DEFINED | DTF_REQUEST_INLINE; cdec->mNumVars = mLocalIndex; } @@ -3238,6 +3324,8 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex if (bdec && bdec->mDefaultConstructor) { + bdec = bdec->ToMutableType(); + Expression* vexp = new Expression(ndec->mLocation, EX_VARIABLE); vexp->mDecType = ndec->mBase; vexp->mDecValue = ndec; @@ -3844,8 +3932,7 @@ Expression* Parser::ParseSimpleExpression(bool lhs) { Expression* nexp = new Expression(mScanner->mLocation, EX_TYPECAST); nexp->mDecType = exp->mDecType; - nexp->mLeft = exp; - nexp->mRight = ParsePrefixExpression(false); + nexp->mLeft = ParsePrefixExpression(false); exp = nexp->ConstantFold(mErrors); } } @@ -3882,6 +3969,36 @@ Expression* Parser::ParseSimpleExpression(bool lhs) return exp; } +Declaration* Parser::MemberLookup(Declaration* dtype, const Ident* ident, int & offset) +{ + Declaration* mdec = dtype->mScope->Lookup(ident); + offset = 0; + + if (!mdec) + { + Declaration* bcdec = dtype->mBase; + + while (bcdec) + { + int noffset; + Declaration* ndec = MemberLookup(bcdec->mBase, ident, noffset); + if (ndec) + { + if (mdec) + mErrors->Error(mScanner->mLocation, EERR_DUPLICATE_DEFINITION, "Multiple definitions for member", ident); + else + { + mdec = ndec; + offset = noffset + bcdec->mOffset; + } + } + bcdec = bcdec->mNext; + } + } + + return mdec; +} + Expression* Parser::ParseQualify(Expression* exp) { @@ -3896,7 +4013,8 @@ Expression* Parser::ParseQualify(Expression* exp) nexp->mLeft = exp; if (mScanner->mToken == TK_IDENT) { - Declaration* mdec = dtype->mScope->Lookup(mScanner->mTokenIdent); + int moffset; + Declaration* mdec = MemberLookup(dtype, mScanner->mTokenIdent, moffset); if (mdec) { @@ -4207,8 +4325,7 @@ Expression* Parser::ParsePostfixExpression(bool lhs) { Expression* nexp = new Expression(mScanner->mLocation, EX_TYPECAST); nexp->mDecType = exp->mDecType; - nexp->mLeft = exp; - nexp->mRight = pexp; + nexp->mLeft = pexp; exp = nexp->ConstantFold(mErrors); } } diff --git a/oscar64/Parser.h b/oscar64/Parser.h index 6e749f7..0ff0b9c 100644 --- a/oscar64/Parser.h +++ b/oscar64/Parser.h @@ -82,6 +82,8 @@ protected: Expression* ParseStatement(void); Expression* ParseSwitchStatement(void); + Declaration* MemberLookup(Declaration* dtype, const Ident * ident, int& offset); + Expression* ParseQualify(Expression * exp); int OverloadDistance(Declaration* pdec, Expression* pexp);