Add non constant structured initializers

This commit is contained in:
drmortalwombat 2024-09-29 14:31:05 +02:00
parent bf5f5a807c
commit daeb3ddfdd
9 changed files with 824 additions and 248 deletions

View File

@ -124,8 +124,8 @@ public:
{ {
head.succ = l.head.succ; head.succ = l.head.succ;
head.pred = l.head.pred; head.pred = l.head.pred;
head.succ->pred = head; head.succ->pred = (listnode<T> *)&head;
head.pred->succ = head; head.pred->succ = (listnode<T> *)&head;
l.head.succ = (listnode<T> *)&(l.head); l.head.succ = (listnode<T> *)&(l.head);
l.head.pred = (listnode<T> *)&(l.head); l.head.pred = (listnode<T> *)&(l.head);
} }
@ -136,8 +136,8 @@ public:
{ {
head.succ = l.head.succ; head.succ = l.head.succ;
head.pred = l.head.pred; head.pred = l.head.pred;
head.succ->pred = head; head.succ->pred = (listnode<T> *)&head;
head.pred->succ = head; head.pred->succ = (listnode<T> *)&head;
l.head.succ = (listnode<T> *)&(l.head); l.head.succ = (listnode<T> *)&(l.head);
l.head.pred = (listnode<T> *)&(l.head); l.head.pred = (listnode<T> *)&(l.head);
return *this; return *this;

View File

@ -156,6 +156,21 @@ Expression::~Expression(void)
} }
Expression* Expression::ListAppend(Expression* lexp)
{
if (lexp)
{
Expression* nexp = new Expression(mLocation, EX_LIST);
nexp->mLeft = lexp;
nexp->mRight = this;
nexp->mDecType = mDecType;
return nexp;
}
else
return this;
}
void Expression::Dump(int ident) const void Expression::Dump(int ident) const
{ {
for (int i = 0; i < ident; i++) for (int i = 0; i < ident; i++)

View File

@ -259,6 +259,7 @@ public:
Expression* ConstantFold(Errors * errors, LinkerSection* dataSection, Linker * linker = nullptr); Expression* ConstantFold(Errors * errors, LinkerSection* dataSection, Linker * linker = nullptr);
Expression* ConstantDereference(Errors* errors, LinkerSection* dataSection); Expression* ConstantDereference(Errors* errors, LinkerSection* dataSection);
bool HasSideEffects(void) const; bool HasSideEffects(void) const;
Expression* ListAppend(Expression* lexp);
bool IsSame(const Expression* exp) const; bool IsSame(const Expression* exp) const;
bool IsRValue(void) const; bool IsRValue(void) const;

View File

@ -101,6 +101,8 @@ enum ErrorID
EERR_INVALID_FOLD_EXPRESSION, EERR_INVALID_FOLD_EXPRESSION,
ERRR_INSTANTIATE_ABSTRACT_CLASS, ERRR_INSTANTIATE_ABSTRACT_CLASS,
ERRR_INVALID_GOTO, ERRR_INVALID_GOTO,
EERR_INVALID_INITIALIZER,
EERR_INVALID_CONSTEXPR, EERR_INVALID_CONSTEXPR,
EERR_DOUBLE_FREE, EERR_DOUBLE_FREE,

View File

@ -4486,6 +4486,13 @@ bool InterInstruction::RemoveUnusedResultInstructions(InterInstruction* pre, Num
changed = true; changed = true;
} }
else if (mCode == IC_COPY && !mVolatile && mSrc[0].mTemp < 0 && mSrc[1].mTemp < 0 && mSrc[0].mMemory == mSrc[1].mMemory &&
mSrc[0].mVarIndex == mSrc[1].mVarIndex && mSrc[0].mLinkerObject == mSrc[1].mLinkerObject && mSrc[0].mIntConst == mSrc[1].mIntConst)
{
mNumOperands = 0;
mCode = IC_NONE;
changed = true;
}
else if (mDst.mTemp != -1) else if (mDst.mTemp != -1)
{ {
if (!requiredTemps[mDst.mTemp] && mDst.mTemp >= 0) if (!requiredTemps[mDst.mTemp] && mDst.mTemp >= 0)
@ -4632,7 +4639,14 @@ bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray&
} }
else if (mCode == IC_COPY) else if (mCode == IC_COPY)
{ {
if (mSrc[1].mMemory == IM_LOCAL) if (!mVolatile && mSrc[0].mTemp < 0 && mSrc[1].mTemp < 0 && mSrc[0].mMemory == mSrc[1].mMemory &&
mSrc[0].mVarIndex == mSrc[1].mVarIndex && mSrc[0].mLinkerObject == mSrc[1].mLinkerObject && mSrc[0].mIntConst == mSrc[1].mIntConst)
{
mSrc[0].mTemp = -1;
mCode = IC_NONE;
changed = true;
}
else if (mSrc[1].mMemory == IM_LOCAL)
{ {
if (localVars[mSrc[1].mVarIndex]->mAliased) if (localVars[mSrc[1].mVarIndex]->mAliased)
; ;
@ -8015,8 +8029,8 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSetsForward(const GrowingVariab
case IC_LOAD: case IC_LOAD:
vr = ins->mDst.mRange; vr = ins->mDst.mRange;
if (ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mMemory == IM_FPARAM) if (ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mMemory == IM_FPARAM && ins->mSrc[0].mIntConst == 0)
vr.Limit(mLocalParamValueRange[ins->mSrc[0].mVarIndex + int(ins->mSrc[0].mIntConst)]); vr.Limit(mLocalParamValueRange[ins->mSrc[0].mVarIndex]);
#if 1 #if 1
if (ins->mDst.mType == IT_INT8) if (ins->mDst.mType == IT_INT8)
{ {
@ -8721,8 +8735,8 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSetsForward(const GrowingVariab
} }
else if (ins->mCode == IC_STORE) else if (ins->mCode == IC_STORE)
{ {
if (ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mMemory == IM_FPARAM) if (ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mMemory == IM_FPARAM && ins->mSrc[0].mIntConst == 0)
mLocalParamValueRange[ins->mSrc[1].mVarIndex + int(ins->mSrc[1].mIntConst)] = ins->mSrc[0].mRange; mLocalParamValueRange[ins->mSrc[1].mVarIndex] = ins->mSrc[0].mRange;
} }
assert(mProc->mLocalValueRange.Size() == mExitRequiredTemps.Size()); assert(mProc->mLocalValueRange.Size() == mExitRequiredTemps.Size());
@ -22554,7 +22568,7 @@ void InterCodeProcedure::Close(void)
{ {
GrowingTypeArray tstack(IT_NONE); GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "bm_init"); CheckFunc = !strcmp(mIdent->mString, "foo");
CheckCase = false; CheckCase = false;
mEntryBlock = mBlocks[0]; mEntryBlock = mBlocks[0];

View File

@ -556,12 +556,48 @@ InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* p
} }
} }
if (ins->mConst.mIntConst < min || ins->mConst.mIntConst > max)
{
int64 min = 0, max = 0;
if (type->mFlags & DTF_SIGNED)
{
switch (type->mSize)
{
case 1:
min = -128; max = 127;
break;
case 2:
min = -32768; max = 32767;
break;
case 4:
min = -2147483648LL; max = 2147483647LL;
break;
}
}
else
{
switch (type->mSize)
{
case 1:
max = 255;
break;
case 2:
max = 65535;
break;
case 4:
max = 429467295LL;
break;
}
}
if (ins->mConst.mIntConst < min || ins->mConst.mIntConst > max) if (ins->mConst.mIntConst < min || ins->mConst.mIntConst > max)
{ {
mErrors->Error(exp->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated"); mErrors->Error(exp->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated");
} }
} }
} }
}
v.mType = type; v.mType = type;
} }

View File

@ -3,6 +3,7 @@
#include "Assembler.h" #include "Assembler.h"
#include "MachineTypes.h" #include "MachineTypes.h"
#include "Constexpr.h" #include "Constexpr.h"
#include "NumberSet.h"
Parser::Parser(Errors* errors, Scanner* scanner, CompilationUnits* compilationUnits) Parser::Parser(Errors* errors, Scanner* scanner, CompilationUnits* compilationUnits)
: mErrors(errors), mScanner(scanner), mCompilationUnits(compilationUnits) : mErrors(errors), mScanner(scanner), mCompilationUnits(compilationUnits)
@ -1668,7 +1669,492 @@ uint8* Parser::ParseStringLiteral(int & msize)
return d; return d;
} }
Expression* Parser::ParseInitExpression(Declaration* dtype, bool inner) Expression* Parser::DefaultInitExpression(Expression* vexp)
{
Expression* exp = nullptr;
Declaration* dtype = vexp->mDecType;
if (dtype->mType == DT_TYPE_INTEGER)
{
Expression* rexp = new Expression(mScanner->mLocation, EX_CONSTANT);
rexp->mDecValue = TheZeroIntegerConstDeclaration;
rexp->mDecType = dtype;
exp = new Expression(rexp->mLocation, EX_INITIALIZATION);
exp->mToken = TK_ASSIGN;
exp->mLeft = vexp;
exp->mRight = rexp;
exp->mDecType = dtype;
}
else
{
mErrors->Error(mScanner->mLocation, EERR_INVALID_INITIALIZER, "Invalid initializer");
exp = new Expression(mScanner->mLocation, EX_VOID);
}
return exp;
}
Expression* Parser::CloneVarInitExpression(Expression* vexp, Expression* iexp, Expression* qexp)
{
if (!iexp)
return nullptr;
else if (iexp == qexp)
return vexp;
else
{
Expression* nexp = new Expression(iexp->mLocation, iexp->mType);
nexp->mToken = iexp->mToken;
nexp->mConst = iexp->mConst;
nexp->mDecType = iexp->mDecType;
nexp->mDecValue = iexp->mDecValue;
nexp->mLeft = CloneVarInitExpression(vexp, iexp->mLeft, qexp);
nexp->mRight = CloneVarInitExpression(vexp, iexp->mRight, qexp);
return nexp;
}
}
Expression* Parser::ParseVarInitExpression(Expression* vexp, bool inner)
{
Expression* exp = nullptr;
Declaration* dtype = vexp->mDecType;
if (dtype->mType == DT_TYPE_ARRAY && mScanner->mToken == TK_STRING && dtype->mBase->mType == DT_TYPE_INTEGER && dtype->mBase->mSize == 1)
{
int ds = dtype->mSize;
uint8* d = ParseStringLiteral(ds);
if (!(dtype->mFlags & DTF_DEFINED))
{
dtype->mFlags |= DTF_DEFINED;
dtype->mSize = int(ds);
}
Declaration * dec = new Declaration(mScanner->mLocation, DT_CONST_DATA);
dec->mBase = dtype;
dec->mSize = dtype->mSize;
dec->mSection = mDataSection;
dec->mData = d;
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
cexp->mDecValue = dec;
cexp->mDecType = dtype;
exp = new Expression(mScanner->mLocation, EX_INITIALIZATION);
exp->mToken = TK_ASSIGN;
exp->mLeft = vexp;
exp->mRight = cexp;
exp->mDecType = dtype;
if (ds > dtype->mSize + 1)
mErrors->Error(mScanner->mLocation, EERR_CONSTANT_INITIALIZER, "String constant is too large for char array");
}
else if ((dtype->mType == DT_TYPE_STRUCT || dtype->mType == DT_TYPE_UNION) && ConsumeTokenIf(TK_OPEN_BRACE))
{
NumberSet fset(dtype->mSize);
bool isconst = true;
Declaration* edec = dtype->mParams;
for(;;)
{
if (ConsumeTokenIf(TK_DOT))
{
if (mScanner->mToken == TK_IDENT)
{
Declaration * ttype = dtype;
Declaration* ndec = ttype->mScope->Lookup(mScanner->mTokenIdent, SLEVEL_SCOPE);
while (!ndec && ttype->mBase)
{
ttype = ttype->mBase->mBase;
ndec = ttype->mScope->Lookup(mScanner->mTokenIdent, SLEVEL_SCOPE);
}
if (ndec)
edec = ndec;
else
mErrors->Error(mScanner->mLocation, EERR_CONSTANT_INITIALIZER, "Struct member not found", mScanner->mTokenIdent);
mScanner->NextToken();
ConsumeToken(TK_ASSIGN);
}
else
mErrors->Error(mScanner->mLocation, EERR_CONSTANT_INITIALIZER, "Identifier expected");
}
if (!edec)
break;
fset += edec->mOffset;
Expression* qexp = new Expression(mScanner->mLocation, EX_QUALIFY);
qexp->mLeft = vexp;
qexp->mDecValue = edec;
qexp->mDecType = edec->mBase;
Expression* nexp = ParseVarInitExpression(qexp);
if (nexp->mType != EX_INITIALIZATION || nexp->mRight->mType != EX_CONSTANT)
isconst = false;
exp = nexp->ListAppend(exp);
if (dtype->mType == DT_TYPE_UNION)
break;
edec = edec->mNext;
if (!ConsumeTokenIf(TK_COMMA))
break;
}
ConsumeToken(TK_CLOSE_BRACE);
if (isconst)
{
Declaration * csdec = new Declaration(mScanner->mLocation, DT_CONST_STRUCT);
csdec->mBase = dtype;
csdec->mSize = dtype->mSize;
csdec->mSection = mDataSection;
Declaration* last = nullptr;
Expression* lexp = exp;
while (lexp)
{
Expression* rexp;
if (lexp->mType == EX_LIST)
{
rexp = lexp->mRight;
lexp = lexp->mLeft;
}
else
{
rexp = lexp;
lexp = nullptr;
}
Declaration* cidec = CopyConstantInitializer(rexp->mLeft->mDecValue->mOffset, rexp->mDecType, rexp->mRight);
if (cidec)
{
cidec->mBits = rexp->mLeft->mDecValue->mBits;
cidec->mShift = rexp->mLeft->mDecValue->mShift;
}
if (last)
last->mNext = cidec;
else
csdec->mParams = cidec;
last = cidec;
}
if (exp)
{
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
cexp->mDecValue = csdec;
cexp->mDecType = dtype;
exp = new Expression(exp->mLocation, EX_INITIALIZATION);
exp->mToken = TK_ASSIGN;
exp->mLeft = vexp;
exp->mRight = cexp;
}
}
else if (dtype->mType == DT_TYPE_STRUCT)
{
edec = dtype->mParams;
while (edec)
{
if (!fset[edec->mOffset])
{
fset += edec->mOffset;
Expression* qexp = new Expression(mScanner->mLocation, EX_QUALIFY);
qexp->mLeft = vexp;
qexp->mDecValue = edec;
qexp->mDecType = edec->mBase;
Expression* nexp = DefaultInitExpression(qexp);
exp = nexp->ListAppend(exp);
}
edec = edec->mNext;
}
}
if (exp)
exp->mDecType = dtype;
}
else if (dtype->mType == DT_TYPE_ARRAY && (inner || ConsumeTokenIf(TK_OPEN_BRACE)))
{
if (inner && ConsumeTokenIf(TK_OPEN_BRACE))
inner = false;
int index = 0, stride = dtype->mBase->mSize, size = dtype->mSize / stride, mindex = 0;
if (!(dtype->mFlags & DTF_DEFINED))
size = 0x10000;
NumberSet fset(size);
bool isconst = true;
for (;;)
{
int nrep = 1;
if (ConsumeTokenIf(TK_OPEN_BRACKET))
{
Expression* istart = ParseRExpression();
if (istart->mType != EX_CONSTANT || istart->mDecValue->mType != DT_CONST_INTEGER)
mErrors->Error(mScanner->mLocation, EERR_CONSTANT_INITIALIZER, "Constant index expected");
else
{
index = int(istart->mDecValue->mInteger);
if (index >= size)
mErrors->Error(mScanner->mLocation, EERR_CONSTANT_INITIALIZER, "Constant initializer out of range");
if (ConsumeTokenIf(TK_ELLIPSIS))
{
Expression* iend = ParseRExpression();
if (iend->mType != EX_CONSTANT || iend->mDecValue->mType != DT_CONST_INTEGER)
mErrors->Error(mScanner->mLocation, EERR_CONSTANT_INITIALIZER, "Constant index expected");
else
{
nrep = int(iend->mDecValue->mInteger - istart->mDecValue->mInteger + 1);
if (size + nrep > dtype->mSize)
mErrors->Error(mScanner->mLocation, EERR_CONSTANT_INITIALIZER, "Constant initializer out of range");
}
}
}
ConsumeToken(TK_CLOSE_BRACKET);
ConsumeToken(TK_ASSIGN);
}
if (index > mindex)
mindex = index;
if (index < size)
fset += index;
Expression* qexp = new Expression(mScanner->mLocation, EX_INDEX);
qexp->mLeft = vexp;
qexp->mRight = new Expression(mScanner->mLocation, EX_CONSTANT);
qexp->mRight->mDecType = TheUnsignedIntTypeDeclaration;
qexp->mRight->mDecValue = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
qexp->mRight->mDecValue->mSize = 2;
qexp->mRight->mDecValue->mInteger = index;
qexp->mRight->mDecValue->mBase = TheUnsignedIntTypeDeclaration;
qexp->mDecType = dtype->mBase;
Expression* nexp = ParseVarInitExpression(qexp, true);
if (nexp->mType != EX_INITIALIZATION || nexp->mRight->mType != EX_CONSTANT)
isconst = false;
exp = nexp->ListAppend(exp);
index++;
for (int i = 1; i < nrep; i++)
{
if (index > mindex)
mindex = index;
if (index < size)
fset += index;
Expression* rqexp = new Expression(mScanner->mLocation, EX_INDEX);
rqexp->mLeft = vexp;
rqexp->mRight = new Expression(mScanner->mLocation, EX_CONSTANT);
rqexp->mRight->mDecType = TheUnsignedIntTypeDeclaration;
rqexp->mRight->mDecValue = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
rqexp->mRight->mDecValue->mSize = 2;
rqexp->mRight->mDecValue->mInteger = index;
rqexp->mRight->mDecValue->mBase = TheUnsignedIntTypeDeclaration;
rqexp->mDecType = dtype->mBase;
Expression* rnexp = CloneVarInitExpression(rqexp, nexp, qexp);
exp = rnexp->ListAppend(exp);
index++;
}
if (inner && index >= size)
break;
if (!ConsumeTokenIf(TK_COMMA))
break;
if (inner && mScanner->mToken == TK_OPEN_BRACKET)
{
mScanner->UngetToken(TK_COMMA);
break;
}
if (mScanner->mToken == TK_CLOSE_BRACE)
break;
}
if (!inner)
{
ConsumeTokenIf(TK_COMMA);
ConsumeToken(TK_CLOSE_BRACE);
}
if (!(dtype->mFlags & DTF_DEFINED))
{
size = mindex + 1;
dtype->mSize = size * dtype->mBase->mSize;
dtype->mFlags |= DTF_DEFINED;
}
if (isconst)
{
Declaration* csdec = new Declaration(mScanner->mLocation, DT_CONST_STRUCT);
csdec->mBase = dtype;
csdec->mSize = dtype->mSize;
csdec->mSection = mDataSection;
Declaration* last = nullptr;
Expression* lexp = exp;
while (lexp)
{
Expression* rexp;
if (lexp->mType == EX_LIST)
{
rexp = lexp->mRight;
lexp = lexp->mLeft;
}
else
{
rexp = lexp;
lexp = nullptr;
}
Declaration* cidec = CopyConstantInitializer(int(rexp->mLeft->mRight->mDecValue->mInteger) * dtype->Stride(), rexp->mDecType, rexp->mRight);
if (last)
last->mNext = cidec;
else
csdec->mParams = cidec;
last = cidec;
}
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
cexp->mDecValue = csdec;
cexp->mDecType = dtype;
exp = new Expression(exp->mLocation, EX_INITIALIZATION);
exp->mToken = TK_ASSIGN;
exp->mLeft = vexp;
exp->mRight = cexp;
}
else
{
for (int i = 0; i < size; i++)
{
if (!fset[i])
{
fset += i;
Expression* qexp = new Expression(mScanner->mLocation, EX_INDEX);
qexp->mLeft = vexp;
qexp->mRight = new Expression(mScanner->mLocation, EX_CONSTANT);
qexp->mRight->mDecType = TheUnsignedIntTypeDeclaration;
qexp->mRight->mDecValue = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
qexp->mRight->mDecValue->mSize = 2;
qexp->mRight->mDecValue->mInteger = i;
qexp->mRight->mDecValue->mBase = TheUnsignedIntTypeDeclaration;
qexp->mDecType = dtype->mBase;
Expression* nexp = DefaultInitExpression(qexp);
exp = nexp->ListAppend(exp);
}
}
}
exp->mDecType = dtype;
}
else if (dtype->mType == DT_TYPE_AUTO)
{
exp = ParseRExpression();
}
else if (dtype->mDefaultConstructor)
{
Declaration* fcons = dtype->mScope ? dtype->mScope->Lookup(dtype->mIdent->PreMangle("+"), SLEVEL_CLASS) : nullptr;
if (dtype->mFlags & DTF_PURE_VIRTUAL)
mErrors->Error(mScanner->mLocation, ERRR_INSTANTIATE_ABSTRACT_CLASS, "Cannot instantiate abstract class", dtype->mIdent);
if (fcons)
{
Declaration* mtype = dtype->ToMutableType();
Expression* rexp = ParseRExpression();
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
cexp->mDecValue = fcons;
cexp->mDecType = cexp->mDecValue->mBase;
Expression* fexp = new Expression(mScanner->mLocation, EX_CALL);
fexp->mLeft = cexp;
fexp->mRight = rexp;
Expression* texp = new Expression(mScanner->mLocation, EX_PREFIX);
texp->mToken = TK_BINARY_AND;
texp->mLeft = vexp;
texp->mDecType = new Declaration(mScanner->mLocation, DT_TYPE_POINTER);
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
texp->mDecType->mBase = mtype;
texp->mDecType->mSize = 2;
if (fexp->mRight)
{
Expression* lexp = new Expression(mScanner->mLocation, EX_LIST);
lexp->mLeft = texp;
lexp->mRight = fexp->mRight;
fexp->mRight = lexp;
}
else
fexp->mRight = texp;
fexp = ResolveOverloadCall(fexp);
Expression* dexp = nullptr;
if (dtype->mDestructor)
{
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
cexp->mDecValue = dtype->mDestructor;
cexp->mDecType = cexp->mDecValue->mBase;
dexp = new Expression(mScanner->mLocation, EX_CALL);
dexp->mLeft = cexp;
dexp->mRight = texp;
}
Expression* nexp = new Expression(mScanner->mLocation, EX_CONSTRUCT);
nexp->mLeft = new Expression(mScanner->mLocation, EX_LIST);
nexp->mLeft->mLeft = fexp;
nexp->mLeft->mRight = dexp;
nexp->mRight = vexp;
nexp->mDecType = vexp->mDecType;
exp = nexp;
}
}
else
{
Expression* rexp = ParseRExpression();
rexp = CoerceExpression(rexp, dtype);
exp = new Expression(rexp->mLocation, EX_INITIALIZATION);
exp->mToken = TK_ASSIGN;
exp->mLeft = vexp;
exp->mRight = rexp;
exp->mDecType = dtype;
}
return exp;
}
Expression* Parser::ParseConstInitExpression(Declaration* dtype, bool inner)
{ {
Expression* exp = nullptr; Expression* exp = nullptr;
Declaration* dec; Declaration* dec;
@ -1767,7 +2253,7 @@ Expression* Parser::ParseInitExpression(Declaration* dtype, bool inner)
ConsumeToken(TK_ASSIGN); ConsumeToken(TK_ASSIGN);
} }
Expression* texp = ParseInitExpression(dtype->mBase, true); Expression* texp = ParseConstInitExpression(dtype->mBase, true);
texp = texp->ConstantFold(mErrors, mDataSection); texp = texp->ConstantFold(mErrors, mDataSection);
for (int i = 0; i < nrep; i++) for (int i = 0; i < nrep; i++)
{ {
@ -1846,7 +2332,7 @@ Expression* Parser::ParseInitExpression(Declaration* dtype, bool inner)
if (mdec) if (mdec)
{ {
Expression* texp = ParseInitExpression(mdec->mBase); Expression* texp = ParseConstInitExpression(mdec->mBase);
Declaration* cdec = CopyConstantInitializer(mdec->mOffset, mdec->mBase, texp); Declaration* cdec = CopyConstantInitializer(mdec->mOffset, mdec->mBase, texp);
if (cdec) if (cdec)
@ -4997,7 +5483,17 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
} }
else else
{ {
ndec->mValue = ParseInitExpression(ndec->mBase); if (member || (ndec->mFlags & (DTF_STATIC | DTF_GLOBAL)))
ndec->mValue = ParseConstInitExpression(ndec->mBase);
else
{
Expression* vexp = new Expression(ndec->mLocation, EX_VARIABLE);
vexp->mDecType = ndec->mBase;
vexp->mDecValue = ndec;
ndec->mValue = ParseVarInitExpression(vexp);
}
ndec->mBase = ndec->mBase->DeduceAuto(ndec->mValue->mDecType); ndec->mBase = ndec->mBase->DeduceAuto(ndec->mValue->mDecType);
if (ndec->mFlags & DTF_GLOBAL) if (ndec->mFlags & DTF_GLOBAL)
@ -5012,6 +5508,11 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
} }
if ((mCompilerOptions & COPT_CPLUSPLUS) && ndec->mType == DT_VARIABLE && !pthis && !(storageFlags & DTF_EXTERN)) if ((mCompilerOptions & COPT_CPLUSPLUS) && ndec->mType == DT_VARIABLE && !pthis && !(storageFlags & DTF_EXTERN))
{
if (ndec->mValue && ndec->mValue->mType == EX_CONSTRUCT && ndec->mValue->mRight && ndec->mValue->mRight->mDecValue == ndec)
{
}
else
{ {
// Find default constructor // Find default constructor
@ -5089,54 +5590,6 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
int offset = 0; int offset = 0;
lexp = BuildVariableArrayInit(texp, bpdec, ndec->mValue->mDecValue, 0, offset); lexp = BuildVariableArrayInit(texp, bpdec, ndec->mValue->mDecValue, 0, offset);
#if 0
Declaration * pdec = ndec->mValue->mDecValue->mParams;
while (pdec)
{
if (pdec->mType == DT_CONST_CONSTRUCTOR)
{
if (offset != pdec->mOffset)
mErrors->Error(pdec->mLocation, EERR_INVALID_CLASS_INITIALIZER, "Incomplete class initializer list");
Declaration* icdec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
icdec->mBase = TheUnsignedIntTypeDeclaration;
icdec->mInteger = pdec->mOffset / ndec->mBase->mBase->mSize;
Expression* icexp = new Expression(mScanner->mLocation, EX_CONSTANT);
icexp->mDecType = icdec->mBase;
icexp->mDecValue = icdec;
Expression* mexp = new Expression(mScanner->mLocation, EX_BINARY);
mexp->mToken = TK_ADD;
mexp->mLeft = texp;
mexp->mRight = icexp;
mexp->mDecType = bpdec;
pdec->mValue->mLeft->mLeft->mRight->mLeft = mexp;
pdec->mValue->mLeft->mRight = nullptr;
pdec->mValue->mRight = nullptr;
if (lexp)
{
Expression* nexp = new Expression(mScanner->mLocation, EX_LIST);
nexp->mLeft = lexp;
nexp->mRight = pdec->mValue;
lexp = nexp;
}
else
lexp = pdec->mValue;
offset += ndec->mBase->mBase->mSize;
}
else
mErrors->Error(pdec->mLocation, EERR_INVALID_CLASS_INITIALIZER, "Invalid class initializer");
pdec = pdec->mNext;
}
#endif
if (offset != ndec->mSize) if (offset != ndec->mSize)
mErrors->Error(pdec->mLocation, EERR_INVALID_CLASS_INITIALIZER, "Incomplete class initializer list"); mErrors->Error(pdec->mLocation, EERR_INVALID_CLASS_INITIALIZER, "Incomplete class initializer list");
@ -5193,7 +5646,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
ndec->mValue = nexp; ndec->mValue = nexp;
ndec->mFlags |= DTF_VAR_ALIASING; ndec->mFlags |= DTF_VAR_ALIASING;
} }
else else if (member || (ndec->mFlags & (DTF_STATIC | DTF_GLOBAL)))
mErrors->Error(ndec->mValue->mLocation, EERR_INVALID_CLASS_INITIALIZER, "Invalid class initializer list"); mErrors->Error(ndec->mValue->mLocation, EERR_INVALID_CLASS_INITIALIZER, "Invalid class initializer list");
} }
else else
@ -5260,6 +5713,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
mErrors->Error(ndec->mLocation, EERR_NO_DEFAULT_CONSTRUCTOR, "No default constructor for class", ndec->mBase->mIdent); mErrors->Error(ndec->mLocation, EERR_NO_DEFAULT_CONSTRUCTOR, "No default constructor for class", ndec->mBase->mIdent);
} }
} }
}
if (storageFlags & DTF_EXPORT) if (storageFlags & DTF_EXPORT)
{ {
@ -5331,7 +5785,11 @@ Expression* Parser::ParseDeclarationExpression(Declaration * pdec)
if (dec->mValue && !(dec->mFlags & DTF_GLOBAL)) if (dec->mValue && !(dec->mFlags & DTF_GLOBAL))
{ {
if ((mCompilerOptions & COPT_CPLUSPLUS) && dec->mValue->mType == EX_CONSTRUCT) if (dec->mValue->mType == EX_INITIALIZATION || dec->mValue->mType == EX_LIST)
{
nexp = dec->mValue;
}
else if ((mCompilerOptions & COPT_CPLUSPLUS) && dec->mValue->mType == EX_CONSTRUCT)
{ {
nexp = dec->mValue; nexp = dec->mValue;
@ -5808,21 +6266,10 @@ Expression* Parser::ParseCastExpression(Expression* exp)
{ {
if (mScanner->mToken == TK_OPEN_BRACE) if (mScanner->mToken == TK_OPEN_BRACE)
{ {
Declaration* cdec = new Declaration(mScanner->mLocation, DT_VARIABLE);
cdec->mFlags |= DTF_CONST | DTF_STATIC | DTF_GLOBAL;
cdec->mBase = exp->mDecType;
Expression* cexp = new Expression(mScanner->mLocation, EX_VARIABLE);
cexp->mDecValue = cdec;
cdec->mValue = ParseInitExpression(cdec->mBase);
cdec->mSection = mDataSection;
cdec->mSize = cdec->mBase->mSize;
if (mFunctionType) if (mFunctionType)
{ {
Declaration* vdec = new Declaration(mScanner->mLocation, DT_VARIABLE); Declaration* vdec = new Declaration(mScanner->mLocation, DT_VARIABLE);
vdec->mBase = cdec->mBase; vdec->mBase = exp->mDecType;
vdec->mVarIndex = mLocalIndex++; vdec->mVarIndex = mLocalIndex++;
vdec->mFlags |= DTF_DEFINED; vdec->mFlags |= DTF_DEFINED;
vdec->mSize = vdec->mBase->mSize; vdec->mSize = vdec->mBase->mSize;
@ -5831,19 +6278,41 @@ Expression* Parser::ParseCastExpression(Expression* exp)
nexp->mDecValue = vdec; nexp->mDecValue = vdec;
nexp->mDecType = vdec->mBase; nexp->mDecType = vdec->mBase;
Expression* iexp = new Expression(mScanner->mLocation, EX_INITIALIZATION); Expression* iexp = ParseVarInitExpression(nexp);
iexp->mLeft = nexp; if (iexp)
iexp->mRight = cexp; {
iexp->mDecType = cdec->mBase; if (iexp->mType == EX_INITIALIZATION || iexp->mType == EX_CONSTRUCT)
cdec->mBase = cdec->mBase->ToConstType();
exp = iexp; exp = iexp;
else
{
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTRUCT);
cexp->mLeft = iexp;
cexp->mRight = nexp;
cexp->mDecType = vdec->mBase;
exp = cexp;
}
} }
else else
exp = cexp; exp = nexp;
}
else
{
Declaration* cdec = new Declaration(mScanner->mLocation, DT_VARIABLE);
cdec->mFlags |= DTF_CONST | DTF_STATIC | DTF_GLOBAL;
cdec->mBase = exp->mDecType;
Expression* cexp = new Expression(mScanner->mLocation, EX_VARIABLE);
cexp->mDecValue = cdec;
cdec->mValue = ParseConstInitExpression(cdec->mBase);
cdec->mSection = mDataSection;
cdec->mSize = cdec->mBase->mSize;
cexp->mDecType = cdec->mBase; cexp->mDecType = cdec->mBase;
exp = cexp;
}
} }
else else
{ {
@ -6884,6 +7353,44 @@ Expression* Parser::CoerceExpression(Expression* exp, Declaration* type)
while (type->mType == DT_TYPE_REFERENCE || type->mType == DT_TYPE_RVALUEREF) while (type->mType == DT_TYPE_REFERENCE || type->mType == DT_TYPE_RVALUEREF)
type = type->mBase; type = type->mBase;
if (type->mType == DT_TYPE_POINTER && tdec->mType == DT_TYPE_INTEGER && exp->mType == EX_CONSTANT && exp->mDecValue->mInteger == 0)
{
if (mCompilerOptions & COPT_CPLUSPLUS)
mErrors->Error(exp->mLocation, EWARN_NUMERIC_0_USED_AS_NULLPTR, "Numeric 0 used for nullptr");
Expression* nexp = new Expression(exp->mLocation, EX_CONSTANT);
nexp->mDecType = TheNullPointerTypeDeclaration;
nexp->mDecValue = TheNullptrConstDeclaration;
return nexp;
}
else if (type->mType == DT_TYPE_INTEGER && tdec->mType == DT_TYPE_INTEGER && exp->mType == EX_CONSTANT && (type->mSize != tdec->mSize || (type->mFlags & DTF_SIGNED) != (tdec->mFlags & DTF_SIGNED)))
{
int64 sval = 1ULL << (8 * type->mSize);
int64 v = exp->mDecValue->mInteger;
if (type->mFlags & DTF_SIGNED)
{
if (v < - (sval >> 1) || v >= (sval >> 1))
mErrors->Error(exp->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated");
v &= (sval - 1);
if (v & (sval >> 1))
v -= sval;
}
else
{
if (v < 0 || v >= sval)
mErrors->Error(exp->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated");
v &= (sval - 1);
}
Expression* ex = new Expression(exp->mLocation, EX_CONSTANT);
Declaration* dec = new Declaration(exp->mLocation, DT_CONST_INTEGER);
dec->mBase = type;
dec->mInteger = v;
ex->mDecValue = dec;
ex->mDecType = type;
return ex;
}
if (tdec->mType == DT_TYPE_STRUCT) if (tdec->mType == DT_TYPE_STRUCT)
{ {
Declaration* fexp = tdec->mScope->Lookup(Ident::Unique("(cast)")); Declaration* fexp = tdec->mScope->Lookup(Ident::Unique("(cast)"));

View File

@ -72,8 +72,11 @@ protected:
Declaration* ParseStructDeclaration(uint64 flags, DecType dt, Declaration* ptempl = nullptr); Declaration* ParseStructDeclaration(uint64 flags, DecType dt, Declaration* ptempl = nullptr);
Declaration* CopyConstantInitializer(int offset, Declaration* dtype, Expression* exp); Declaration* CopyConstantInitializer(int offset, Declaration* dtype, Expression* exp);
Expression* ParseInitExpression(Declaration* dtype, bool inner = false); Expression* ParseConstInitExpression(Declaration* dtype, bool inner = false);
Expression* ParseDeclarationExpression(Declaration* pdec); Expression* ParseDeclarationExpression(Declaration* pdec);
Expression* DefaultInitExpression(Expression* vexp);
Expression* ParseVarInitExpression(Expression* lexp, bool inner = false);
Expression* CloneVarInitExpression(Expression* vexp, Expression* iexp, Expression * qexp);
Declaration* ParsePostfixDeclaration(void); Declaration* ParsePostfixDeclaration(void);
Declaration* ReverseDeclaration(Declaration* odec, Declaration* bdec); Declaration* ReverseDeclaration(Declaration* odec, Declaration* bdec);

View File

@ -534,7 +534,7 @@ int main2(int argc, const char** argv)
printf("Starting %s %s\n", strProductName, strProductVersion); printf("Starting %s %s\n", strProductName, strProductVersion);
} }
compiler->WriteErrorFile(targetPath); compiler->RemoveErrorFile(targetPath);
{ {
char dstring[100], tstring[100]; char dstring[100], tstring[100];
@ -569,8 +569,6 @@ int main2(int argc, const char** argv)
if (diskPath[0]) if (diskPath[0])
d64 = new DiskImage(diskPath); d64 = new DiskImage(diskPath);
compiler->RemoveErrorFile(targetPath);
compiler->WriteOutputFile(targetPath, d64); compiler->WriteOutputFile(targetPath, d64);
if (d64) if (d64)