Implement base class constructors

This commit is contained in:
drmortalwombat 2023-06-28 22:14:29 +02:00
parent 478f93922d
commit 3d6b60c9f4
6 changed files with 226 additions and 58 deletions

View File

@ -447,46 +447,46 @@ Expression* Expression::ConstantFold(Errors * errors)
return ex; return ex;
} }
#endif #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); Expression* ex = new Expression(mLocation, EX_CONSTANT);
Declaration* dec = new Declaration(mLocation, DT_CONST_ADDRESS); Declaration* dec = new Declaration(mLocation, DT_CONST_ADDRESS);
dec->mBase = mLeft->mDecType; dec->mBase = mDecType;
dec->mInteger = mRight->mDecValue->mInteger; dec->mInteger = mLeft->mDecValue->mInteger;
ex->mDecValue = dec; ex->mDecValue = dec;
ex->mDecType = mLeft->mDecType; ex->mDecType = mDecType;
return ex; 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); Expression* ex = new Expression(mLocation, EX_CONSTANT);
ex->mDecValue = mRight->mDecValue; ex->mDecValue = mLeft->mDecValue;
ex->mDecType = mLeft->mDecType; ex->mDecType = mDecType;
return ex; 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); Expression* ex = new Expression(mLocation, EX_CONSTANT);
Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER); Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER);
dec->mBase = mLeft->mDecType; dec->mBase = mDecType;
dec->mInteger = int64(mRight->mDecValue->mNumber); dec->mInteger = int64(mLeft->mDecValue->mNumber);
ex->mDecValue = dec; ex->mDecValue = dec;
ex->mDecType = mLeft->mDecType; ex->mDecType = mDecType;
return ex; 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 sval = 1ULL << (8 * mDecType->mSize);
int64 v = mRight->mDecValue->mInteger & (sval - 1); int64 v = mLeft->mDecValue->mInteger & (sval - 1);
if (mLeft->mDecType->mFlags & DTF_SIGNED) if (mDecType->mFlags & DTF_SIGNED)
{ {
if (v & (sval >> 1)) if (v & (sval >> 1))
v -= sval; v -= sval;
@ -494,23 +494,23 @@ Expression* Expression::ConstantFold(Errors * errors)
Expression* ex = new Expression(mLocation, EX_CONSTANT); Expression* ex = new Expression(mLocation, EX_CONSTANT);
Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER); Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER);
dec->mBase = mLeft->mDecType; dec->mBase = mDecType;
dec->mInteger = v; dec->mInteger = v;
ex->mDecValue = dec; ex->mDecValue = dec;
ex->mDecType = mLeft->mDecType; ex->mDecType = mDecType;
return ex; 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); Expression* ex = new Expression(mLocation, EX_CONSTANT);
Declaration* dec = new Declaration(mLocation, DT_CONST_FLOAT); Declaration* dec = new Declaration(mLocation, DT_CONST_FLOAT);
dec->mBase = mLeft->mDecType; dec->mBase = mDecType;
dec->mNumber = double(mRight->mDecValue->mInteger); dec->mNumber = double(mLeft->mDecValue->mInteger);
ex->mDecValue = dec; ex->mDecValue = dec;
ex->mDecType = mLeft->mDecType; ex->mDecType = mDecType;
return ex; return ex;
} }
} }
@ -781,7 +781,8 @@ Expression* Expression::ConstantFold(Errors * errors)
Declaration::Declaration(const Location& loc, DecType type) Declaration::Declaration(const Location& loc, DecType type)
: mLocation(loc), mEndLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mQualIdent(nullptr), : mLocation(loc), mEndLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mQualIdent(nullptr),
mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0), 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), mDefaultConstructor(nullptr), mDestructor(nullptr), mCopyConstructor(nullptr), mCopyAssignment(nullptr),
mVectorConstructor(nullptr), mVectorDestructor(nullptr), mVectorCopyConstructor(nullptr), mVectorCopyAssignment(nullptr), mVectorConstructor(nullptr), mVectorDestructor(nullptr), mVectorCopyConstructor(nullptr), mVectorCopyAssignment(nullptr),
mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1), mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1),
@ -938,12 +939,49 @@ Declaration* Declaration::ToConstType(void)
ndec->mParams = mParams; ndec->mParams = mParams;
ndec->mIdent = mIdent; ndec->mIdent = mIdent;
ndec->mQualIdent = mQualIdent; ndec->mQualIdent = mQualIdent;
ndec->mDefaultConstructor = mDefaultConstructor;
ndec->mCopyConstructor = mCopyConstructor;
ndec->mVectorConstructor = mVectorConstructor;
ndec->mVectorCopyConstructor = mVectorCopyConstructor;
ndec->mMutable = this;
mConst = ndec; mConst = ndec;
} }
return mConst; 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 bool Declaration::IsSubType(const Declaration* dec) const
{ {
if (this == dec) if (this == dec)
@ -978,7 +1016,15 @@ bool Declaration::IsSubType(const Declaration* dec) const
return true; return true;
if (dec->mBase) if (dec->mBase)
return IsSubType(dec->mBase); {
Declaration* bcdec = dec->mBase;
while (bcdec)
{
if (IsSubType(bcdec->mBase))
return true;
bcdec = bcdec->mNext;
}
}
return false; return false;
} }

View File

@ -49,6 +49,7 @@ enum DecType
DT_FUNCTION_REF, DT_FUNCTION_REF,
DT_LABEL_REF, DT_LABEL_REF,
DT_NAMESPACE, DT_NAMESPACE,
DT_BASECLASS
}; };
// TypeFlags // TypeFlags
@ -222,7 +223,7 @@ public:
Location mLocation, mEndLocation; Location mLocation, mEndLocation;
DecType mType; DecType mType;
Token mToken; Token mToken;
Declaration * mBase, * mParams, * mNext, * mPrev, * mConst; Declaration * mBase, * mParams, * mNext, * mPrev, * mConst, * mMutable;
Declaration * mDefaultConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment; Declaration * mDefaultConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment;
Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment; Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment;
@ -254,6 +255,8 @@ public:
void SetDefined(void); void SetDefined(void);
Declaration* ToConstType(void); Declaration* ToConstType(void);
Declaration* ToMutableType(void);
Declaration* ToStriped(int stripe); Declaration* ToStriped(int stripe);
Declaration* ToStriped(Errors* errors); Declaration* ToStriped(Errors* errors);
Declaration* Clone(void); Declaration* Clone(void);

View File

@ -823,7 +823,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
case EX_TYPE: case EX_TYPE:
break; break;
case EX_TYPECAST: case EX_TYPECAST:
return Analyze(exp->mRight, procDec, false); return Analyze(exp->mLeft, procDec, false);
break; break;
case EX_LOGICAL_AND: case EX_LOGICAL_AND:
ldec = Analyze(exp->mLeft, procDec, false); ldec = Analyze(exp->mLeft, procDec, false);

View File

@ -3739,11 +3739,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
case EX_TYPECAST: 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); 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); 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->mOperator = (vr.mType->mFlags & DTF_SIGNED) ? IA_INT2FLOAT : IA_UINT2FLOAT;
ins->mSrc[0].mType = IT_INT16; ins->mSrc[0].mType = IT_INT16;
ins->mSrc[0].mTemp = stemp; 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); ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
block->Append(ins); 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); 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].mType = InterTypeOf(vr.mType);
ins->mSrc[0].mTemp = vr.mTemp; ins->mSrc[0].mTemp = vr.mTemp;
ins->mDst.mType = IT_INT16; ins->mDst.mType = IT_INT16;
ins->mDst.mTemp = proc->AddTemporary(IT_INT16); ins->mDst.mTemp = proc->AddTemporary(IT_INT16);
block->Append(ins); block->Append(ins);
if (exp->mLeft->mDecType->mSize == 1) if (exp->mDecType->mSize == 1)
{ {
InterInstruction* xins = new InterInstruction(exp->mLocation, IC_TYPECAST); InterInstruction* xins = new InterInstruction(exp->mLocation, IC_TYPECAST);
xins->mSrc[0].mType = IT_INT16; xins->mSrc[0].mType = IT_INT16;
xins->mSrc[0].mTemp = ins->mDst.mTemp; 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); xins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
block->Append(xins); block->Append(xins);
ins = 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 // 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 // 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"); 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); vr = Dereference(proc, exp, block, vr);
return CoerceType(proc, exp, block, vr, exp->mLeft->mDecType); return CoerceType(proc, exp, block, vr, exp->mDecType);
} }
else else
{ {
@ -3829,12 +3829,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
ins->mCode = IC_TYPECAST; ins->mCode = IC_TYPECAST;
ins->mSrc[0].mType = InterTypeOf(vr.mType); ins->mSrc[0].mType = InterTypeOf(vr.mType);
ins->mSrc[0].mTemp = vr.mTemp; 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); ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
block->Append(ins); block->Append(ins);
} }
return ExValue(exp->mLeft->mDecType, ins->mDst.mTemp); return ExValue(exp->mDecType, ins->mDst.mTemp);
} }
break; break;

View File

@ -104,8 +104,12 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
{ {
if (pdec->mType == DT_TYPE_STRUCT) 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->mSize = pdec->mSize;
dec->mBase = bcdec;
} }
else else
mErrors->Error(mScanner->mLocation, ERRO_NOT_A_BASE_CLASS, "Not a base class", dec->mIdent); 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->mDecType = pthis->mBase;
thisexp->mLeft = pthisexp; 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; Declaration* dec = pthis->mBase->mParams;
if (dec) if (dec)
{ {
dec = dec->Last(); dec = dec->Last();
while (dec) while (dec)
{ {
@ -1387,7 +1426,28 @@ void Parser::BuildMemberConstructor(Declaration* pthis, Declaration* cfunc)
if (ExpectToken(TK_IDENT)) if (ExpectToken(TK_IDENT))
{ {
Declaration* dec = pthis->mBase->mScope->Lookup(mScanner->mTokenIdent); 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); Expression* qexp = new Expression(pthis->mLocation, EX_QUALIFY);
qexp->mLeft = thisexp; qexp->mLeft = thisexp;
@ -1415,7 +1475,7 @@ void Parser::BuildMemberConstructor(Declaration* pthis, Declaration* cfunc)
void Parser::AddDefaultConstructors(Declaration* pthis) void Parser::AddDefaultConstructors(Declaration* pthis)
{ {
bool simpleDestructor = true, simpleAssignment = true; bool simpleDestructor = true, simpleAssignment = true, simpleConstructor = true, simpleCopy = true;
char dname[100]; char dname[100];
strcpy_s(dname, "~"); strcpy_s(dname, "~");
@ -1455,6 +1515,20 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
adec = adec->mNext; 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; Declaration* dec = pthis->mBase->mParams;
while (dec) while (dec)
{ {
@ -1470,6 +1544,10 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
{ {
if (bdec->mDestructor) if (bdec->mDestructor)
simpleDestructor = false; simpleDestructor = false;
if (bdec->mDefaultConstructor)
simpleConstructor = false;
if (bdec->mCopyConstructor)
simpleCopy = false;
if (bdec->mCopyAssignment) if (bdec->mCopyAssignment)
simpleAssignment = false; simpleAssignment = false;
} }
@ -1514,7 +1592,10 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
cdec->mValue = new Expression(mScanner->mLocation, EX_VOID); cdec->mValue = new Expression(mScanner->mLocation, EX_VOID);
} }
}
if (!simpleConstructor)
{
if (!pthis->mBase->mDefaultConstructor) if (!pthis->mBase->mDefaultConstructor)
{ {
Declaration* ctdec = new Declaration(mScanner->mLocation, DT_TYPE_FUNCTION); 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); cdec->mValue = new Expression(mScanner->mLocation, EX_VOID);
} }
}
if (!simpleCopy)
{
if (!pthis->mBase->mCopyConstructor) if (!pthis->mBase->mCopyConstructor)
{ {
Declaration* ctdec = new Declaration(mScanner->mLocation, DT_TYPE_FUNCTION); Declaration* ctdec = new Declaration(mScanner->mLocation, DT_TYPE_FUNCTION);
@ -2567,8 +2651,10 @@ void Parser::ParseVariableInit(Declaration* ndec)
if (fcons) if (fcons)
{ {
Declaration* mtype = ndec->mBase->ToMutableType();
Expression* vexp = new Expression(mScanner->mLocation, EX_VARIABLE); Expression* vexp = new Expression(mScanner->mLocation, EX_VARIABLE);
vexp->mDecType = ndec->mBase; vexp->mDecType = mtype;
vexp->mDecValue = ndec; vexp->mDecValue = ndec;
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT); Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
@ -2584,7 +2670,7 @@ void Parser::ParseVariableInit(Declaration* ndec)
texp->mLeft = vexp; texp->mLeft = vexp;
texp->mDecType = new Declaration(mScanner->mLocation, DT_TYPE_POINTER); texp->mDecType = new Declaration(mScanner->mLocation, DT_TYPE_POINTER);
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED; texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
texp->mDecType->mBase = ndec->mBase; texp->mDecType->mBase = mtype;
texp->mDecType->mSize = 2; texp->mDecType->mSize = 2;
if (fexp->mRight) if (fexp->mRight)
@ -2793,7 +2879,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
cdec->mValue = ParseFunction(cdec->mBase); cdec->mValue = ParseFunction(cdec->mBase);
cdec->mFlags |= DTF_DEFINED; cdec->mFlags |= DTF_DEFINED | DTF_REQUEST_INLINE;
cdec->mNumVars = mLocalIndex; cdec->mNumVars = mLocalIndex;
} }
@ -2880,7 +2966,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
cdec->mValue = ParseFunction(cdec->mBase); cdec->mValue = ParseFunction(cdec->mBase);
cdec->mFlags |= DTF_DEFINED; cdec->mFlags |= DTF_DEFINED | DTF_REQUEST_INLINE;
cdec->mNumVars = mLocalIndex; cdec->mNumVars = mLocalIndex;
} }
@ -3238,6 +3324,8 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
if (bdec && bdec->mDefaultConstructor) if (bdec && bdec->mDefaultConstructor)
{ {
bdec = bdec->ToMutableType();
Expression* vexp = new Expression(ndec->mLocation, EX_VARIABLE); Expression* vexp = new Expression(ndec->mLocation, EX_VARIABLE);
vexp->mDecType = ndec->mBase; vexp->mDecType = ndec->mBase;
vexp->mDecValue = ndec; vexp->mDecValue = ndec;
@ -3844,8 +3932,7 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
{ {
Expression* nexp = new Expression(mScanner->mLocation, EX_TYPECAST); Expression* nexp = new Expression(mScanner->mLocation, EX_TYPECAST);
nexp->mDecType = exp->mDecType; nexp->mDecType = exp->mDecType;
nexp->mLeft = exp; nexp->mLeft = ParsePrefixExpression(false);
nexp->mRight = ParsePrefixExpression(false);
exp = nexp->ConstantFold(mErrors); exp = nexp->ConstantFold(mErrors);
} }
} }
@ -3882,6 +3969,36 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
return exp; 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) Expression* Parser::ParseQualify(Expression* exp)
{ {
@ -3896,7 +4013,8 @@ Expression* Parser::ParseQualify(Expression* exp)
nexp->mLeft = exp; nexp->mLeft = exp;
if (mScanner->mToken == TK_IDENT) if (mScanner->mToken == TK_IDENT)
{ {
Declaration* mdec = dtype->mScope->Lookup(mScanner->mTokenIdent); int moffset;
Declaration* mdec = MemberLookup(dtype, mScanner->mTokenIdent, moffset);
if (mdec) if (mdec)
{ {
@ -4207,8 +4325,7 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
{ {
Expression* nexp = new Expression(mScanner->mLocation, EX_TYPECAST); Expression* nexp = new Expression(mScanner->mLocation, EX_TYPECAST);
nexp->mDecType = exp->mDecType; nexp->mDecType = exp->mDecType;
nexp->mLeft = exp; nexp->mLeft = pexp;
nexp->mRight = pexp;
exp = nexp->ConstantFold(mErrors); exp = nexp->ConstantFold(mErrors);
} }
} }

View File

@ -82,6 +82,8 @@ protected:
Expression* ParseStatement(void); Expression* ParseStatement(void);
Expression* ParseSwitchStatement(void); Expression* ParseSwitchStatement(void);
Declaration* MemberLookup(Declaration* dtype, const Ident * ident, int& offset);
Expression* ParseQualify(Expression * exp); Expression* ParseQualify(Expression * exp);
int OverloadDistance(Declaration* pdec, Expression* pexp); int OverloadDistance(Declaration* pdec, Expression* pexp);